poj 1191 棋盘分割
http://poj.org/problem?id=1191
这道题先是预处理,在dp处理。
dp[k][x1][y1][x2][y2]=min(min(dp[k+1][x1][y1][a][y2]+s[a+1][y1][x2][y2],dp[k+1][a+1][y1][x2][y2]+s[x1][y1][a][y2]),min(dp[k+1][x1][y1][x2][b]+s[x1][b][x2][y2],dp[k+1][x1][b+1][x2][y2]+s[x1][y1][x2][b]);
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int inf=1<<30; 8 9 int dp[15][15][15][15][15]; 10 int g[20][20]; 11 int ans[20][20][20][20]; 12 int n; 13 14 void inti() 15 { 16 for(int x=0; x<9; x++) 17 { 18 for(int y=0; y<9; y++) 19 { 20 for(int x1=x; x1<9; x1++) 21 { 22 for(int y1=y; y1<9; y1++) 23 { 24 int c=0; 25 for(int i=x; i<=x1; i++) 26 { 27 for(int j=y; j<=y1; j++) 28 { 29 c+=g[i][j]; 30 } 31 } 32 ans[x][y][x1][y1]=c*c; 33 ans[x1][y1][x][y]=c*c; 34 ans[x][y1][x1][y]=c*c; 35 ans[x1][y][x][y1]=c*c; 36 } 37 } 38 } 39 } 40 } 41 42 int deal(int k,int x1,int y1,int x2,int y2) 43 { 44 if(dp[k][x1][y1][x2][y2]>=0) return dp[k][x1][y1][x2][y2]; 45 if(k==n-1) return ans[x1][y1][x2][y2]; 46 dp[k][x1][y1][x2][y2]=inf; 47 int ans1=0; 48 for(int a=x1; a<x2; a++) 49 { 50 ans1=min(deal(k+1,x1,y1,a,y2)+ans[a+1][y1][x2][y2],deal(k+1,a+1,y1,x2,y2)+ans[x1][y1][a][y2]); 51 dp[k][x1][y1][x2][y2]=min(dp[k][x1][y1][x2][y2],ans1); 52 } 53 for(int b=y1; b<y2; b++) 54 { 55 ans1=min(deal(k+1,x1,y1,x2,b)+ans[x1][b+1][x2][y2],deal(k+1,x1,b+1,x2,y2)+ans[x1][y1][x2][b]); 56 dp[k][x1][y1][x2][y2]=min(dp[k][x1][y1][x2][y2],ans1); 57 } 58 return dp[k][x1][y1][x2][y2]; 59 } 60 61 int main() 62 { 63 while(scanf("%d",&n)!=EOF) 64 { 65 memset(dp,-1,sizeof(dp)); 66 int cnt=0; 67 for(int i=0; i<8; i++) 68 { 69 for(int j=0; j<8; j++) 70 { 71 scanf("%d",&g[i][j]); 72 cnt+=g[i][j]; 73 } 74 } 75 inti(); 76 deal(0,0,0,7,7); 77 printf("%.3f\n",sqrt((dp[0][0][0][7][7]*1.0)/n-((cnt*1.0)/n)*((cnt*1.0)/n))); 78 } 79 return 0; 80 }