博客
关于我
NOI1999 棋盘分割
阅读量:477 次
发布时间:2019-03-06

本文共 2063 字,大约阅读时间需要 6 分钟。

题目:棋盘分割

网址:

将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘。(每次切割都只能沿着棋盘格子的边进行)

原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。

现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。

均方差,其中平均值,xi为第 i 块矩形棋盘的总分。

请编程对给出的棋盘及n,求出均方差的最小值。

输入格式

第1行为一个整数n。

第2行至第9行每行为8个小于100的非负整数,表示棋盘上相应格子的分值。每行相邻两数之间用一个空格分隔。

输出格式

输出最小均方差值(四舍五入精确到小数点后三位)。

数据范围

1<n<15

输入样例:
31 1 1 1 1 1 1 31 1 1 1 1 1 1 11 1 1 1 1 1 1 11 1 1 1 1 1 1 11 1 1 1 1 1 1 11 1 1 1 1 1 1 11 1 1 1 1 1 1 01 1 1 1 1 1 0 3
输出样例:
1.633

这道题会发现最终影响结果大小只与分的块有关(分块哈哈);

二维区间DP,最终注意以下细节即可:

1.精度问题(如果代码过不去多半是这个问题);
2.初始化(全部初始化为正无穷,不然还是容易错)。

代码如下:

#include
#include
#include
#include
using namespace std;const int SIZE = 15 + 2;int n, s[SIZE][SIZE] = {};double ave = 0.000, dp[SIZE][SIZE][SIZE][SIZE][SIZE];double min(double x, double y){ return x < y ? x : y;}double compute(int a1, int b1, int a2, int b2){ double p = s[a2][b2] - s[a2][b1 - 1] - s[a1 - 1][b2] + s[a1 - 1][b1 - 1]; return (p - ave) * (p - ave)/ n;}int main(){ scanf("%d", &n); for(int i = 1; i <= 8; ++ i) { for(int j = 1; j <= 8; ++ j) { scanf("%d", &s[i][j]); s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1]; } } ave = (double)s[8][8] / n; for(int i = 1; i <= 8; ++ i) for(int l = 1; l <= 8; ++ l) for(int j = i; j <= 8; ++ j) for(int r = l; r <= 8; ++ r) dp[0][i][j][l][r] = compute(i, l, j, r); for(int p = 1; p < n; ++ p) { for(int i = 1; i <= 8; ++ i) { for(int j = i; j <= 8; ++ j) { for(int l = 1; l <= 8; ++ l) { for(int r = l; r <= 8; ++ r) { double &ans = dp[p][i][j][l][r]; ans = 1e9; for(int k = i; k < j; ++ k) { ans = min(ans, dp[0][k + 1][j][l][r] + dp[p - 1][i][k][l][r]); ans = min(ans, dp[0][i][k][l][r] + dp[p - 1][k + 1][j][l][r]); } for(int k = l; k < r; ++ k) { ans = min(ans, dp[0][i][j][k + 1][r] + dp[p - 1][i][j][l][k]); ans = min(ans, dp[0][i][j][l][k] + dp[p - 1][i][j][k + 1][r]); } } } } } } printf("%.3lf\n", (double)sqrt(dp[n - 1][1][8][1][8])); return 0;}

转载地址:http://johbz.baihongyu.com/

你可能感兴趣的文章
Mysql 整形列的字节与存储范围
查看>>
mysql 断电数据损坏,无法启动
查看>>
MySQL 日期时间类型的选择
查看>>
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>
MySQL 是如何加锁的?
查看>>
MySQL 是怎样运行的 - InnoDB数据页结构
查看>>
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询数据库所有表的字段信息
查看>>
【Java基础】什么是面向对象?
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>
MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
查看>>
mysql 死锁 Deadlock found when trying to get lock; try restarting transaction
查看>>