首页 > 代码库 > POJ 1191 棋盘分割(DP)
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 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。