题意:将一个8*8的棋盘(每一个单元正方形有个分值)沿直线(竖或横)割掉一块,留下一块,对留下的这块继续这样操作,总共进行n - 1次,得到n块(1 < n < 15)矩形,每一个矩形的分值就是单元正方形的分值的和,问这n个矩形的最小均方差。

题目链接:

id=1191">http://poj.org/problem?

id=1191

——>>此题中。均方差比較,等价于方差比較,等价于平方和比較。

状态:dp[x1][y1][x2][y2][i]表示将(x1, y1)到(x2, y2)的矩形切割i次的最小平方和。

状态转移方程:dp[x1][y1][x2][y2][i] = min(dp[x1][y1][j][y2][i - 1] + nSquare[j + 1][y1][x2][y2], dp[j + 1][y1][x2][y2][i - 1] + nSquare[x1][y1][j][y2], );(水平方向分割)

dp[x1][y1][x2][y2][i] = min(dp[x1][y1][x2][j][i - 1] + nSquare[x1][j + 1][x2][y2], dp[x1][j + 1][x2][y2][i - 1] + nSquare[x1][y1][x2][j]);(竖直方向分割)

两个方向再取最小值。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath> using std::sqrt;
using std::min; const int WIDTH = 8;
const int MAXN = 15 + 1;
const int INF = 0x3f3f3f3f; int a[WIDTH + 1][WIDTH + 1];
int nSum[WIDTH + 1][WIDTH + 1][WIDTH + 1][WIDTH + 1];
int nSquare[WIDTH + 1][WIDTH + 1][WIDTH + 1][WIDTH + 1];
int dp[WIDTH + 1][WIDTH + 1][WIDTH + 1][WIDTH + 1][MAXN]; void Init()
{
memset(nSum, 0, sizeof(nSum));
for (int x1 = 1; x1 <= WIDTH; ++x1)
{
for (int y1 = 1; y1 <= WIDTH; ++y1)
{
for (int x2 = x1; x2 <= WIDTH; ++x2)
{
for (int y2 = y1; y2 <= WIDTH; ++y2)
{
nSum[x1][y1][x2][y2] = nSum[x1][y1][x2 - 1][y2] + nSum[x1][y1][x2][y2 - 1] - nSum[x1][y1][x2 - 1][y2 - 1] + a[x2][y2];
nSquare[x1][y1][x2][y2] = nSum[x1][y1][x2][y2] * nSum[x1][y1][x2][y2];
dp[x1][y1][x2][y2][0] = nSquare[x1][y1][x2][y2];
}
}
}
}
} void Dp(int n)
{
for (int i = 1; i <= n - 1; ++i)
{
for (int x1 = WIDTH; x1 >= 1; --x1)
{
for (int y1 = 1; y1 <= WIDTH; ++y1)
{
for (int x2 = x1; x2 <= WIDTH; ++x2)
{
for (int y2 = y1; y2 <= WIDTH; ++y2)
{
dp[x1][y1][x2][y2][i] = INF;
for (int j = x1; j < x2; ++j)
{
dp[x1][y1][x2][y2][i] = min(dp[x1][y1][x2][y2][i], dp[x1][y1][j][y2][i - 1] + nSquare[j + 1][y1][x2][y2]);
dp[x1][y1][x2][y2][i] = min(dp[x1][y1][x2][y2][i], dp[j + 1][y1][x2][y2][i - 1] + nSquare[x1][y1][j][y2]);
}
for (int j = y1; j < y2; ++j)
{
dp[x1][y1][x2][y2][i] = min(dp[x1][y1][x2][y2][i], dp[x1][y1][x2][j][i - 1] + nSquare[x1][j + 1][x2][y2]);
dp[x1][y1][x2][y2][i] = min(dp[x1][y1][x2][y2][i], dp[x1][j + 1][x2][y2][i - 1] + nSquare[x1][y1][x2][j]);
}
}
}
}
}
}
} void Output(int n)
{
double fAvg = 1.0 * nSum[1][1][8][8] / n;
printf("%.3f\n", sqrt(1.0 * dp[1][1][8][8][n - 1] / n - fAvg * fAvg));
} void Read()
{
for (int i = 1; i <= WIDTH; ++i)
{
for (int j = 1; j <= WIDTH; ++j)
{
scanf("%d", &a[i][j]);
}
}
} int main()
{
int n; while (scanf("%d", &n) == 1)
{
Read();
Init();
Dp(n);
Output(n);
} return 0;
}

poj - 1191 - 棋盘切割(dp)的更多相关文章

  1. poj 1191 棋盘切割 (压缩dp+记忆化搜索)

    一,题意: 中文题 二.分析: 主要利用压缩dp与记忆化搜索思想 三,代码: #include <iostream> #include <stdio.h> #include & ...

  2. poj 1191 棋盘分割(dp + 记忆化搜索)

    题目:http://poj.org/problem?id=1191 黑书116页的例题 将方差公式化简之后就是 每一块和的平方 相加/n , 减去平均值的平方. 可以看出来 方差只与 每一块的和的平方 ...

  3. POJ 1191 棋盘分割(DP)

    题目链接 大体思路看,黑书...其他就是注意搞一个in数组,这样记忆化搜索,貌似比较快. #include <cstdio> #include <cstring> #inclu ...

  4. HDU 2517 / POJ 1191 棋盘分割 区间DP / 记忆化搜索

    题目链接: 黑书 P116 HDU 2157 棋盘分割 POJ 1191 棋盘分割 分析:  枚举所有可能的切割方法. 但如果用递归的方法要加上记忆搜索, 不能会超时... 代码: #include& ...

  5. POJ 1191 棋盘分割 【DFS记忆化搜索经典】

    题目传送门:http://poj.org/problem?id=1191 棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submission ...

  6. POJ - 1191 棋盘分割 记忆递归 搜索dp+数学

    http://poj.org/problem?id=1191 题意:中文题. 题解: 1.关于切割的模拟,用递归 有这样的递归方程(dp方程):f(n,棋盘)=f(n-1,待割的棋盘)+f(1,割下的 ...

  7. (中等) POJ 1191 棋盘分割,DP。

    Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次 ...

  8. POJ 1191 棋盘分割(DP)

    题目链接 题意 : 中文题不详述. 思路 : 黑书上116页讲的很详细.不过你需要在之前预处理一下面积,那样的话之后列式子比较方便一些. 先把均方差那个公式变形, 另X表示x的平均值,两边平方得 平均 ...

  9. POJ 1191 棋盘分割 (区间DP,记忆化搜索)

    题面 思路:分析公式,我们可以发现平均值那一项和我们怎么分的具体方案无关,影响答案的是每个矩阵的矩阵和的平方,由于数据很小,我们可以预处理出每个矩阵的和的平方,执行状态转移. 设dp[l1][r1][ ...

随机推荐

  1. WordPress主题开发:style.css主题信息标记

    在最简单的情况下,一个WordPress主题由两个文件构成: index.php ------------------主模版 style.css -------------------主样式表 而且s ...

  2. ios之如何读取plist

    - (NSDictionary*)contactsInfoFromPlistNamed:(NSString*)plistName { NSString *path = [[NSBundle mainB ...

  3. Library drmframework_jni not found

    http://piotrbuda.eu/2012/06/trying-to-solve-error-491-in-play-store-on-android-emulator.html http:// ...

  4. Java中CAS详解

    在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁 锁机制存在以下问题: (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度延时,引起性能问题. (2 ...

  5. shell单引号与变量、双引号与变量、如何在多重引号里面取到shell变量的值?

    如何在多重引号里面取到shell变量的值? 双引号是不会屏蔽对变量和某些特殊符号的转义的,而单引号里的所有内容都会原封不动的输出,而单引号里再用单引号将变量引起来,变量就又可以正常的显示,有点像数学里 ...

  6. 下载Sourceforge等国内无法下载站点文件的另一种方法

    Sourceforge是一些开源软件经常用到的网站,然而国内的网站一直不稳定,如今是可以访问,但是一直无法下载,今天发现了一种新方法那就是http://www.mirrorservice.org 这个 ...

  7. Linux 动态链接库(.so)的使用

    1. 背景 库:就是已经编写好的,后续可以直接使用的代码. c++静态库:会合入到最终生成的程序,使得结果文件比较大.优点是不再有任何依赖. c++动态库:动态库,一个文件可以多个代码同时使用内存中只 ...

  8. Reverse Words in a String leetcode java

    题目: Given an input string, reverse the string word by word. For example, Given s = "the sky is ...

  9. linux 如何正确的关闭mongodb

    有的朋友说可以通过下面的命令关闭mongodb: killall mongodb #or kill -9 mongo-pid 上面的方法确实可以关闭mongodb,但是正确的做法不是这样子的,mong ...

  10. JS里关于事件的常被考察的知识点:事件流、事件广播、原生JS实现事件代理

    1.JS里面的事件流 DOM2级事件模型中规定了事件流的三个阶段:捕获阶段.目标阶段.冒泡阶段,低版本IE(IE8及以下版本)不支持捕获阶段 捕获事件流:Netscape提出的事件流,即事件由页面元素 ...