不要过于沉溺过去,也不要过于畅想未来,把握现在!

POJ 1191

棋盘分割
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 12698   Accepted: 4503

Description

将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘。(每次切割都只能沿着棋盘格子的边进行)

原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。
均方差,其中平均值,xi为第i块矩形棋盘的总分。
请编程对给出的棋盘及n,求出O'的最小值。

Input

第1行为一个整数n(1 < n < 15)。
第2行至第9行每行为8个小于100的非负整数,表示棋盘上相应格子的分值。每行相邻两数之间用一个空格分隔。

Output

仅一个数,为O'(四舍五入精确到小数点后三位)。

Sample Input

3
1 1 1 1 1 1 1 3
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 3

Sample Output

1.633

Source

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cstdlib>
 6 #include<cmath>
 7 using namespace std;
 8 
 9 const int inf=0x3fffffff;
10 const int maxn=9;
11 
12 int n;
13 int str[maxn][maxn];
14 int dp[16][maxn][maxn][maxn][maxn];
15 bool vis[16][maxn][maxn][maxn][maxn];
16 int sum[maxn][maxn][maxn][maxn];
17 void cal()
18 {
19     int ans=0;
20     memset(sum,0,sizeof(sum));
21     for(int i1=0;i1<=8;i1++)
22          for(int j1=0;j1<=8;j1++)
23           for(int i2=i1;i2<=8;i2++)
24            for(int j2=j1;j2<=8;j2++)
25     {
26         ans=0;
27         for(int i=i1;i<=i2;i++)
28             for(int j=j1;j<=j2;j++)
29         {
30 
31             ans+=str[i][j];
32         }
33         sum[i1][j1][i2][j2]=ans*ans;
34         sum[i1][j2][i2][j1]=ans*ans;
35         sum[i2][j2][i1][j1]=ans*ans;
36         sum[i2][j1][i1][j2]=ans*ans;
37     }
38 }
39 int DP(int k,int x,int y,int xx,int yy)
40 {
41     if(dp[k][x][y][xx][yy]>=0) return dp[k][x][y][xx][yy];
42     if(k==n-1)return sum[x][y][xx][yy];
43     int ans=0;
44     dp[k][x][y][xx][yy]=1<<29;
45     for(int i=x;i<xx;i++)
46     {
47         ans=min(DP(k+1,x,y,i,yy)+sum[i+1][y][xx][yy],DP(k+1,i+1,y,xx,yy)+sum[x][y][i][yy]);
48         dp[k][x][y][xx][yy]=min(ans,dp[k][x][y][xx][yy]);
49     }
50     for(int i=y;i<yy;i++)
51     {
52         ans=min(DP(k+1,x,y,xx,i)+sum[x][i+1][xx][yy],DP(k+1,x,i+1,xx,yy)+sum[x][y][xx][i]);
53         dp[k][x][y][xx][yy]=min(ans,dp[k][x][y][xx][yy]);
54     }
55     return dp[k][x][y][xx][yy];
56 }
57 int main()
58 {
59    //freopen("in.txt","r",stdin);
60     int tol;
61       scanf("%d",&n);
62         tol=0;
63         for(int i=0;i<8;i++)
64             for(int j=0;j<8;j++)
65         {
66             scanf("%d",&str[i][j]);
67             tol+=str[i][j];
68         }
69         cal();
70         memset(dp,-1,sizeof(dp));
71         DP(0,0,0,7,7);
72         double res=sqrt(dp[0][0][0][7][7]*1.0/n-((tol*1.0)/n*(tol*1.0)/n));
73         printf("%.3f\n",res);
74    // }
75     return 0;
76 }

 

posted @ 2015-02-07 15:28  coding_yuan  阅读(185)  评论(0编辑  收藏  举报

不要过于沉溺过去,也不要过于畅想未来,把握现在!