题意:将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘。原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。
根据定义
极差= 1/n * (Σxi^2 - n*xba^2) =Σxi^2/n -xba^2
因为xba^2 =(整个矩形的权值/ N)^2
所以现在只要使Σxi^2 最大 即N个矩形的平方和最小
最后的状态:切割N-1次后,矩形0,0,8,8中的最小平方和
设状态数组 DP[17][9][9][9][9]
有转移方程 DP[i][x1][y1][x2][y2] = Min( DP[i-1][a][y1][x2][y2] + S[x1][y1][a][y2]^2 ,
DP[i-1][x1][y1][a][y2]+S[a][y1][x2][y2]^2 ,
DP[i-1][x1][b][x2][y2]+S[x1][y1][x2][b]^2,
DP[i-1][x1][y1][x2][b]+S[x1][b][x2][y2]^2
x1<a<=x2 ,y1<b<=y2
#include<stdio.h>
#include<string.h>
#include<math.h>
#define Min(a,b) (a<b?a:b)
int N;
int DP[16][9][9][9][9];
int Val[9][9];
int S[9][9];
float Averge2;
int main(){
int i,j,x1,x2,y1,y2,a;
int rowsum,temp;
memset(DP,0,sizeof(DP));
memset(S,0,sizeof(S));
scanf("%d",&N);
for(i=1;i<=8;i++)
for(j=1;j<=8;j++)
scanf("%d",&Val[i][j]);
//Init左上角为00的所有矩形
for(j=1;j<=8;j++)
for(rowsum=0,i=1;i<=8;i++){
rowsum+=Val[i][j];
S[i][j]=S[i][j-1]+rowsum;
}
Averge2=(float)(S[8][8]*S[8][8])/(float)(N*N);
for(i=0;i<=N-1;i++)
for(x1=0;x1<=7;x1++)
for(y1=0;y1<=7;y1++)
for(x2=x1+1;x2<=8;x2++)
for(y2=y1+1;y2<=8;y2++){
if(i==0){
DP[0][x1][y1][x2][y2]=(S[x2][y2]-S[x1][y2]-S[x2][y1]+S[x1][y1]);
DP[0][x1][y1][x2][y2]=DP[0][x1][y1][x2][y2]*DP[0][x1][y1][x2][y2];
continue;
}
DP[i][x1][y1][x2][y2]=100000000;
for(a=x1;a<=x2;a++){
temp=(S[x2][y2]-S[x2][y1]-S[a][y2]+S[a][y1]);
temp=temp*temp;
DP[i][x1][y1][x2][y2]=Min(DP[i-1][x1][y1][a][y2]+temp,DP[i][x1][y1][x2][y2]);
temp=(S[a][y2]-S[a][y1]-S[x1][y2]+S[x1][y1]);
temp=temp*temp;
DP[i][x1][y1][x2][y2]=Min(DP[i-1][a][y1][x2][y2]+temp,DP[i][x1][y1][x2][y2]);
}
for(a=y1;a<=y2;a++){
temp=(S[x2][a]-S[x2][y1]-S[x1][a]+S[x1][y1]);
temp=temp*temp;
DP[i][x1][y1][x2][y2]=Min(DP[i-1][x1][a][x2][y2]+temp,DP[i][x1][y1][x2][y2]);
temp=(S[x2][y2]-S[x2][a]-S[x1][y2]+S[x1][a]);
temp=temp*temp;
DP[i][x1][y1][x2][y2]=Min(DP[i-1][x1][y1][x2][a]+temp,DP[i][x1][y1][x2][y2]);
}
printf("DP[%d][%d][%d][%d][%d]=%d\n",i,x1,y1,x2,y2,DP[i][x1][y1][x2][y2]);
}
printf("%.3f\n",sqrt((float)DP[N-1][0][0][8][8]/N-Averge2));
goto start;
start:return 0;
}
本文探讨了一种将8*8棋盘分割成n块矩形棋盘的方法,目标是使得各矩形棋盘总分的均方差最小。通过定义极差公式并推导转移方程,实现了一种动态规划算法来解决该问题。

92

被折叠的 条评论
为什么被折叠?



