POJ 1191 棋盘分割(DP)

题目链接

题意 : 中文题不详述。

思路 : 黑书上116页讲的很详细。不过你需要在之前预处理一下面积,那样的话之后列式子比较方便一些。

先把均方差那个公式变形,

另X表示x的平均值,两边平方得

平均值是一定的,所以只要让每个矩形的总分的平方和尽量小即可。左上角坐标为(x1,y1)右下角坐标为(x2,y2)的棋盘,设总和为s[][][][],切割k次以后得到k+1块矩形的总分平方和是d[k][][][][],则可以沿着横线切也可以沿着竖线切,然后选一块接着切,递归下去,状态转移方程

d[k,x1,y2,x2,y2] =
min{min{d[k-1,x1,y1,a,y2]+s[a+1,y1,x2,y2],d[k-1,a+1,y1,x2,y2]+s[x1,y1,a,y2]}(x1<=a<x2),min{d[k-1,x1,y2,x2,b]+s[x1,b+1,x2,y2],d[k-1,x1,b+1,x2,y2]+s[x1,y1,x2,b]},(y1<=b<y2)}


 1 //1191
2 #include <stdio.h>
3 #include <iostream>
4 #include <cmath>
5
6 using namespace std ;
7
8 double dp[15][9][9][9][9] ,s[9][9] ;
9 int n ;
10
11 double ss(int x1,int y1,int x2,int y2)
12 {
13 double sss = s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1] ;
14 return sss * sss ;
15 }
16
17 double DFS(int k,int x1,int y1,int x2,int y2)
18 {
19 if(k == 1) return ss(x1,y1,x2,y2) ;
20 if(fabs(dp[k][x1][y1][x2][y2]) > 1e-6) return dp[k][x1][y1][x2][y2] ;
21 double minn = 1 << 29 ;
22 for(int i = x1 ; i < x2 ; i++)
23 minn = min(minn,min(DFS(k-1,x1,y1,i,y2)+ss(i+1,y1,x2,y2),DFS(k-1,i+1,y1,x2,y2)+ss(x1,y1,i,y2))) ;
24 for(int i = y1 ; i < y2 ; i++)
25 minn = min(minn,min(DFS(k-1,x1,y1,x2,i)+ss(x1,i+1,x2,y2),DFS(k-1,x1,i+1,x2,y2)+ss(x1,y1,x2,i))) ;
26 dp[k][x1][y1][x2][y2] = minn ;
27 return minn ;
28 }
29 int main()
30 {
31 scanf("%d",&n) ;
32 int x ;
33 //memset(s,0,sizeof(s)) ;
34 for(int i = 1 ; i <= 8 ; i++)
35 for(int j = 1 ; j <= 8 ; j++)
36 {
37 scanf("%d",&x) ;
38 s[i][j] = x + s[i-1][j]+s[i][j-1]-s[i-1][j-1] ;
39 }
40 printf("%.3lf\n",sqrt(DFS(n,1,1,8,8)/n-(s[8][8]/n)*(s[8][8]/n)) );
41 return 0 ;
42 }

时间: 2024-10-05 08:13:46

POJ 1191 棋盘分割(DP)的相关文章

POJ 1191 棋盘分割

棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11938   Accepted: 4207 Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规

poj - 1191 - 棋盘分割(dp)

题意:将一个8*8的棋盘(每个单元正方形有个分值)沿直线(竖或横)割掉一块,留下一块,对留下的这块继续这样操作,总共进行n - 1次,得到n块(1 < n < 15)矩形,每个矩形的分值就是单元正方形的分值的和,问这n个矩形的最小均方差. 题目链接:http://poj.org/problem?id=1191 -->>此题中,均方差比较,等价于方差比较,等价于平方和比较.. 状态:dp[x1][y1][x2][y2][i]表示将(x1, y1)到(x2, y2)的矩形分割i次的最小

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

Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小. 均方差,其中平均值,xi为第i块矩形棋盘的总分. 请编程对给出的棋盘及n,求出O'的最小值. 题目好像很经典,DP问题,直

POJ 1191 棋盘分割(区间DP)题解

题意:中文题面 思路:不知道直接暴力枚举所有情况行不行... 我们可以把答案转化为 所以答案就是求xi2的最小值,那么我们可以直接用区间DP来写.设dp[x1][y1][x2][y2][k]为x1 y1 到 x2 y2 区间分割为k份的最下平方和,显然k = 1是就是区间和的平方. 写了6层for,写出来自己都不信... 交C++才过... 代码: #include<cmath> #include<stack> #include<cstdio> #include<

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

一,题意: 中文题 二,分析: 主要利用压缩dp与记忆化搜索思想 三,代码: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> using namespace std; const int Big=20000000; int Mat[10][10]; int N; int sum[10][10]; int

POJ百炼——1191棋盘分割

1191:棋盘分割 总时间限制: 1000ms 内存限制: 65536kB 描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行)原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小.均方差,其中平均值,xi为第i块矩形棋盘的总分.请编程对给出的棋盘及

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

一,题意: 中文题 二.分析: 主要利用压缩dp与记忆化搜索思想 三,代码: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> using namespace std; const int Big=20000000; int Mat[10][10]; int N; int sum[10][10]; int

#RANK_3 1191:棋盘分割

总时间限制:  1000ms 内存限制:  65536kB 描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行)原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小.均方差,其中平均值,xi为第i块矩形棋盘的总分.请编程对给出的棋盘及n,求出O'的最

NOI1999 JZYZOJ1289 棋盘分割 dp 方差的数学结论

http://172.20.6.3/Problem_Show.asp?id=1289 除了下标一坨一坨屎一样挺恶心其他都还挺容易的dp,这道题才发现scanf保留小数位是四舍五入的,惊了. f[k][x1][y1][x2][y2] 嗯写的时候猜错结论了,本来以为是求下属分配方案中平方和与平均数平方*k的差最小的方案赋给f,没想到是直接找最小的. 代码 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream>