题目:http://poj.org/problem?id=1191
黑书116页的例题
将方差公式化简之后就是 每一块和的平方 相加/n , 减去平均值的平方。
可以看出来 方差只与 每一块的和的平方有关,所以就是求每个矩形的总分的平方和 尽量小。。。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <cstdlib> 6 #include <algorithm> 7 using namespace std; 8 const int INF = 1<<28; 9 int sum[10][10], d[20][10][10][10][10];//sum存储从【1,1】到【i, j】的和 10 int _min(int a, int b) 11 { 12 return a>b?b:a; 13 } 14 int getsum(int x1, int y1, int x2, int y2) //计算从【x1,y1】到【x2, y2】的和。 15 { 16 return sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1]; 17 } 18 int slove(int k, int x1, int y1, int x2, int y2) 19 { 20 int s1, s2, Min, temp1, temp2; 21 int i; 22 if(d[k][x1][y1][x2][y2]!=-1) //不等于1表示已经求过了,不需要再求了 23 return d[k][x1][y1][x2][y2]; 24 if(k == 1) //表示已经切了n块了,不需要再切了 25 { 26 s1 = getsum(x1, y1, x2, y2); 27 return (d[k][x1][y1][x2][y2] = s1*s1); 28 } 29 Min = INF; 30 for(i = x1; i < x2; i++) //横向切 31 { 32 s1 = getsum(x1, y1, i, y2); 33 s2 = getsum(i+1, y1, x2, y2); 34 temp1 = _min(slove(k-1, i+1, y1, x2, y2)+s1*s1, slove(k-1, x1, y1, i, y2)+s2*s2); 35 if(temp1 < Min) 36 Min = temp1; 37 } 38 for(i = y1; i < y2; i++) //纵向切 39 { 40 s1 = getsum(x1, y1, x2, i); 41 s2 = getsum(x1, i+1, x2, y2); 42 temp2 = _min(slove(k-1, x1, i+1, x2, y2)+s1*s1, slove(k-1, x1, y1, x2, i)+s2*s2); 43 if(temp2 < Min) 44 Min = temp2; 45 } 46 return (d[k][x1][y1][x2][y2] = Min); 47 } 48 int main() 49 { 50 int n, i, j, val, x; 51 double aver, var; 52 while(~scanf("%d", &n)) 53 { 54 memset(d, -1, sizeof(d)); 55 memset(sum, 0, sizeof(sum)); 56 for(i = 1; i <= 8; i++) 57 for(j = 1, x = 0; j <= 8; j++) 58 { 59 scanf("%d", &val); 60 x += val; 61 sum[i][j] = sum[i-1][j] + x; 62 } 63 aver = sum[8][8]*1.0/n; //所有块的平方和 64 int sum_t = slove(n, 1, 1, 8, 8); 65 var = sqrt(sum_t*1.0/n-aver*aver); 66 67 printf("%.3lf ", var); 68 } 69 return 0; 70 }