poj1191 棋盘分割。 dp
连接:http://poj.org/problem?id=1191
思路:额,其实就是直接搞记录一下就可以了。
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <stdlib.h> 6 #include <vector> 7 #include <queue> 8 #include <stack> 9 #include <cmath> 10 #define loop(s,i,n) for(i = s;i < n;i++) 11 #define cl(a,b) memset(a,b,sizeof(a)) 12 int map[10][10]; 13 int sum[10][10][10][10]; 14 int dp[15][10][10][10][10]; 15 double average; 16 int n; 17 using namespace std; 18 void init() 19 { 20 int i,j,ii,jj,iii,jjj; 21 loop(1,i,9) 22 { 23 loop(1,j,9) 24 { 25 loop(i,ii,9) 26 { 27 loop(j,jj,9) 28 { 29 int ans; 30 ans = 0; 31 loop(i,iii,ii+1) 32 loop(j,jjj,jj+1) 33 ans+=map[iii][jjj]; 34 ans = (ans)*(ans); 35 sum[i][j][ii][jj] += ans; 36 } 37 38 } 39 } 40 } 41 } 42 int deal(int k,int x,int y,int xx,int yy) 43 { 44 45 if(dp[k][x][y][xx][yy] >= 0) return dp[k][x][y][xx][yy]; 46 if(k == n) 47 return sum[x][y][xx][yy]; 48 49 int i,j,ans; 50 dp[k][x][y][xx][yy] = 20000000; 51 for(i = x;i <= xx-1;i++) 52 { 53 ans = min(deal(k+1,x,y,i,yy)+sum[i+1][y][xx][yy],deal(k+1,i+1,y,xx,yy)+sum[x][y][i][yy]); 54 dp[k][x][y][xx][yy] = min(ans,dp[k][x][y][xx][yy]); 55 } 56 57 for(j = y;j <= yy-1;j++) 58 { 59 ans = min(deal(k+1,x,y,xx,j)+sum[x][j+1][xx][yy],deal(k+1,x,j+1,xx,yy)+sum[x][y][xx][j]); 60 dp[k][x][y][xx][yy] = min(ans,dp[k][x][y][xx][yy]); 61 } 62 63 return dp[k][x][y][xx][yy]; 64 } 65 int main() 66 { 67 //int n; 68 // 69 // freopen("in.txt","r",stdin); 70 while(~scanf("%d",&n)) 71 { 72 int i,j; 73 average = 0; 74 loop(1,i,9) 75 { 76 loop(1,j,9) 77 scanf("%d",map[i]+j),average += map[i][j]; 78 } 79 80 average = 1.0*average/n; 81 cl(sum,0); 82 cl(dp,-1); 83 init(); 84 deal(1,1,1,8,8); 85 // puts("yes"); 86 87 double ans = sqrt(dp[1][1][1][8][8]*1.0/n-average*average); 88 printf("%.3f",ans); 89 } 90 return 0; 91 }