Poj 1191 棋盘分割
2012-01-22 13:49
405 查看
题目大意:将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘。(每次切割都只能沿着棋盘格子的边进行)
原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。
均方差 ,其中平均值 ,xi为第i块矩形棋盘的总分。
请编程对给出的棋盘及n,求出O'的最小值。
思路:lrj《算法与信息学竞赛》中P116的例题。dp[k][x1][y1][x2][y2]:左上角坐标为(x1,y1),右下角坐标为(x2,y2)
的棋盘,设它把切割k次以后得到的k+1块矩形的总分平方和最小值。
s[x1][y1][x2][y2]:左上角坐标为(x1,y1),右下角坐标为(x2,y2)。
的棋盘的总和的平方
状态转移方程dp[k][x1][y1][x2][y2] =
1)按横的划分: min(dp[k-1][x1][y1][f][y2]+s[f+1][y1][x2][y2] , dp[k-1][f+1][y1][x2][y2]+s[x1][y1][f][y2]);
2)按竖的划分: min(dp[k-1][x1][y1][x2][f]+s[x1][f+1][x2][y2], dp[k-1][x1][f+1][x2][y2]+s[x1][y1][x2][f]);
原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。
均方差 ,其中平均值 ,xi为第i块矩形棋盘的总分。
请编程对给出的棋盘及n,求出O'的最小值。
思路:lrj《算法与信息学竞赛》中P116的例题。dp[k][x1][y1][x2][y2]:左上角坐标为(x1,y1),右下角坐标为(x2,y2)
的棋盘,设它把切割k次以后得到的k+1块矩形的总分平方和最小值。
s[x1][y1][x2][y2]:左上角坐标为(x1,y1),右下角坐标为(x2,y2)。
的棋盘的总和的平方
状态转移方程dp[k][x1][y1][x2][y2] =
1)按横的划分: min(dp[k-1][x1][y1][f][y2]+s[f+1][y1][x2][y2] , dp[k-1][f+1][y1][x2][y2]+s[x1][y1][f][y2]);
2)按竖的划分: min(dp[k-1][x1][y1][x2][f]+s[x1][f+1][x2][y2], dp[k-1][x1][f+1][x2][y2]+s[x1][y1][x2][f]);
/* dp[k][x1][y1][x2][y2]:左上角坐标为(x1,y1),右下角坐标为(x2,y2) 的棋盘,设它把切割k次以后得到的k+1块矩形的总分平方和最小值. s[x1][y1][x2][y2]:左上角坐标为(x1,y1),右下角坐标为(x2,y2) 的棋盘的总和的平方 dp[k][x1][y1][x2][y2] = 1)按横的划分: min(dp[k-1][x1][y1][f][y2]+s[f+1][y1][x2][y2] , dp[k-1][f+1][y1][x2][y2]+s[x1][y1][f][y2]); 2)按竖的划分: min(dp[k-1][x1][y1][x2][f]+s[x1][f+1][x2][y2] , dp[k-1][x1][f+1][x2][y2]+s[x1][y1][x2][f]); */ #include <stdio.h> #include <memory.h> #include <math.h> int n; int dp[16][10][10][10][10]; int data[10][10]; int s[10][10][10][10]; void get_sum(int x1,int y1,int x2,int y2) { int i,j,sum; sum=0; if (s[x1][y1][x2][y2]!=0) return; for (i=x1;i<=x2;i++) { for (j=y1;j<=y2;j++) { sum=sum+data[i][j]; } } s[x1][y1][x2][y2]=sum*sum; } int min_num(int a,int b) { if (a>b) return b; return a; } int main() { int i,j,k,g,h,l,temp; double sum,average,result; scanf("%d",&n); sum=0; for (i=1;i<=8;i++) { for (j=1;j<=8;j++) { scanf("%d",&data[i][j]); sum+=data[i][j]; } } average=sum/n; memset(s,0,sizeof(s)); for (i=1;i<=8;i++) { for (j=1;j<=8;j++) { for (g=i;g<=8;g++) { for (h=j;h<=8;h++) { get_sum(i,j,g,h); dp[0][i][j][g][h]=s[i][j][g][h]; } } } } for (k=1;k<n;k++) { for (i=1;i<=8;i++) { for (j=1;j<=8;j++) { for (g=i;g<=8;g++) { for (h=j;h<=8;h++) { dp[k][i][j][g][h]=10000000; for (l=i;l<g;l++) { get_sum(l+1,j,g,h); temp=min_num(dp[k-1][i][j][l][h]+s[l+1][j][g][h],dp[k-1][l+1][j][g][h]+s[i][j][l][h]); dp[k][i][j][g][h]=min_num(temp, dp[k][i][j][g][h]); } for (l=j;l<h;l++) { get_sum(i,l+1,g,h); temp=min_num(dp[k-1][i][j][g][l]+s[i][l+1][g][h],dp[k-1][i][l+1][g][h]+s[i][j][g][l]); dp[k][i][j][g][h]=min_num(temp, dp[k][i][j][g][h]); } } } } } } result=(double)dp[n-1][1][1][8][8]/n-average*average; printf("%.3lf\n",sqrt(result)); return 0; }
相关文章推荐
- 【poj 1191】棋盘分割 题解&代码(C++)
- POJ 1191 棋盘分割 简单记忆化dfs
- poj 1191 棋盘分割 dp-进阶
- poj 1191 棋盘分割 记忆化搜索
- POJ-1191-棋盘分割
- POJ 1191 棋盘分割
- POJ 1191 棋盘分割 (DP)
- poj1191 [NOI1999] 棋盘分割(dp)
- poj 1191 棋盘分割(dp)
- poj 1191 棋盘分割 动态规划
- poj1191——分割棋盘求最小均方差,记忆化搜索
- POJ 1191 棋盘分割
- poj 1191棋盘分割(递归dp, 记忆化搜索)
- poj 1191 棋盘分割 (DFS+DP思想)
- 【DP】 POJ 1191 棋盘分割 记忆化搜索
- POJ 1191 棋盘分割
- POJ 1191--棋盘分割
- poj1191 棋盘分割(记忆化搜索)
- (POJ 1191)棋盘分割 <DFS>
- POJ-1191 棋盘分割