http://acm.pku.edu.cn/JudgeOnline/problem?id=1191
运用 动态规划, 状态为int d(int k, int x1, int y1, int x2, int y2),表示 左上角为(x1, y1),右下角为(x2, y2)的矩阵被切割成n块时可以达到的最小平方和。
状态转移方程为d(k, x1, y1, 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]), min(d[k-1, x1, y1, x2, b]+s[x1, b+1, x2, y2], d[k-1, x1, b+1, x2, y2]+s[x1, y1, x2, b]))。其中x1<=a<x2, y1<=b<y2。
用一个五维数组s保存计算过的状态。val数组中存放 左上角为(0,0)点与右下角为当前位置的矩形的所有元素的和。
关于WA:在代码第16行没有初始化r,所以一直WA。当把r赋一个较大的值后终于AC了:)
可供参考的链接:http://blog.chinaunix.net/u/26924/showart_653969.html
运用 动态规划, 状态为int d(int k, int x1, int y1, int x2, int y2),表示 左上角为(x1, y1),右下角为(x2, y2)的矩阵被切割成n块时可以达到的最小平方和。
状态转移方程为d(k, x1, y1, 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]), min(d[k-1, x1, y1, x2, b]+s[x1, b+1, x2, y2], d[k-1, x1, b+1, x2, y2]+s[x1, y1, x2, b]))。其中x1<=a<x2, y1<=b<y2。
用一个五维数组s保存计算过的状态。val数组中存放 左上角为(0,0)点与右下角为当前位置的矩形的所有元素的和。
关于WA:在代码第16行没有初始化r,所以一直WA。当把r赋一个较大的值后终于AC了:)
可供参考的链接:http://blog.chinaunix.net/u/26924/showart_653969.html
- #include <stdio.h>
- #include <math.h>
- #define SIZE 8
- #define min(a,b) ((a)<(b)) ? (a) : (b)
- int k;//分割数量
- int val[SIZE+1][SIZE+1];//val中每一个位置存放的是左上角为(0,0)点与右下角为当前位置的矩形的所有元素的和
- int s[15][SIZE+1][SIZE+1][SIZE+1][SIZE+1];//存储各个状态的值
- int sum(int x1, int y1, int x2, int y2)
- {
- int ret;
- ret=val[x2][y2]-val[x2][y1-1]-val[x1-1][y2]+val[x1-1][y1-1];
- return ret*ret;
- }
- int d(int n, int x1, int y1, int x2, int y2)
- {//状态:左上角为(x1, y1),右下角为(x2, y2)的矩阵被切割成n块时可以达到的最小平方和
- int i, j, r=100000000;
- if (s[n][x1][y1][x2][y2]!=-1)
- return s[n][x1][y1][x2][y2];
- else{
- if (n==1 || x1==x2 || y1==y2){
- s[n][x1][y1][x2][y2]=sum(x1,y1,x2,y2);
- return s[n][x1][y1][x2][y2];
- }
- else{
- for (i=x1; i<x2; i++)//竖切
- r=min(r, min(d(n-1, x1, y1, i, y2)+sum(i+1, y1, x2, y2), d(n-1, i+1, y1, x2, y2)+sum(x1, y1, i, y2)));
- for (j=y1; j<y2; j++)//横切
- r=min(r, min(d(n-1, x1, y1, x2, j)+sum(x1, j+1, x2, y2), d(n-1, x1, j+1, x2, y2)+sum(x1, y1, x2, j)));
- s[n][x1][y1][x2][y2]=r;
- return r;
- }
- }
- }
- void ReadFile()//读文件
- {
- int i, j;
- //freopen("poj1191.txt","r", stdin);
- scanf("%d", &k);
- for (i=1; i<=SIZE; i++){
- for (j=1; j<=SIZE; j++)
- scanf("%d", &val[i][j]);
- }
- for (i=0; i<=SIZE; i++)
- val[0][i]=val[i][0]=0;
- for (i=1; i<=SIZE; i++){
- for (j=1; j<=SIZE; j++)
- val[i][j]+=val[i-1][j]+val[i][j-1]-val[i-1][j-1];
- }
- }
- void Initial()//初始化s[][][][][]
- {
- int i, j, x, y, k;
- for (k=0; k<15; k++){
- for (i=0; i<=SIZE; i++)
- for(j=0; j<=SIZE; j++)
- for (x=0; x<=SIZE; x++)
- for (y=0; y<=SIZE; y++)
- s[k][i][j][x][y]=-1;
- }
- }
- void OutPut()
- {
- double res;
- res=sqrt((double)d(k, 1, 1, SIZE, SIZE)/k-pow(sqrt(sum(1, 1, SIZE, SIZE))/k, 2.0));
- printf("%.3f/n", res);
- }
- main(int argc, char *argv[])
- {
- Initial();
- ReadFile();
- OutPut();
- }