POJ 1191 棋盘分割(DP)
大体思路看,黑书。。。其他就是注意搞一个in数组,这样记忆化搜索,貌似比较快。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 using namespace std; 6 #define INF 0x7fffffff 7 int p[10][10],sum[10][10]; 8 double dp[11][11][11][11][21]; 9 int in[11][11][11][11][21]; 10 double s[11][11][11][11]; 11 int dfs(int x1,int y1,int x2,int y2,int k) 12 { 13 int i; 14 if(in[x1][y1][x2][y2][k]) 15 return dp[x1][y1][x2][y2][k]; 16 if(k == 1) 17 { 18 in[x1][y1][x2][y2][k] = 1; 19 return dp[x1][y1][x2][y2][k] = s[x1][y1][x2][y2]; 20 } 21 else 22 { 23 double minz = INF; 24 for(i = x1;i < x2;i ++) 25 { 26 minz = min(dfs(x1,y1,i,y2,k-1)+s[i+1][y1][x2][y2],minz); 27 minz = min(dfs(i+1,y1,x2,y2,k-1)+s[x1][y1][i][y2],minz); 28 } 29 for(i = y1;i < y2;i ++) 30 { 31 minz = min(dfs(x1,y1,x2,i,k-1)+s[x1][i+1][x2][y2],minz); 32 minz = min(dfs(x1,i+1,x2,y2,k-1)+s[x1][y1][x2][i],minz); 33 } 34 in[x1][y1][x2][y2][k] = 1; 35 return dp[x1][y1][x2][y2][k] = minz; 36 } 37 } 38 int main() 39 { 40 int i,j,k,u,v,n,temp; 41 scanf("%d",&n); 42 temp = 0; 43 for(i = 1;i <= 8;i ++) 44 { 45 for(j = 1;j <= 8;j ++) 46 { 47 scanf("%d",&p[i][j]); 48 temp += p[i][j]; 49 } 50 } 51 for(i = 1;i <= 8;i ++) 52 { 53 for(j = 1;j <= 8;j ++) 54 { 55 for(k = 1;k <= 8;k ++) 56 { 57 for(u = 1;u <= 8;u ++) 58 { 59 for(v = 1;v <= n;v ++) 60 dp[i][j][k][u][v] = INF; 61 } 62 } 63 } 64 } 65 for(i = 1;i <= 8;i ++) 66 { 67 for(j = 1;j <= 8;j ++) 68 sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + p[i][j]; 69 } 70 for(i = 1;i <= 8;i ++) 71 { 72 for(j = 1;j <= 8;j ++) 73 { 74 for(k = 1;k <= 8;k ++) 75 { 76 for(u = 1;u <= 8;u ++) 77 { 78 s[i][j][k][u] = sum[k][u]+sum[i-1][j-1]-sum[i-1][u]-sum[k][j-1]; 79 s[i][j][k][u] *= s[i][j][k][u]; 80 } 81 } 82 } 83 } 84 printf("%.3f\n",sqrt(dfs(1,1,8,8,n)*1.0/n-(temp*1.0/n)*(temp*1.0/n))); 85 return 0; 86 }