POJ 1191.cpp

棋盘分割

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

Noi 99

 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 }
时间: 2024-10-13 15:18:42

POJ 1191.cpp的相关文章

POJ 1191 棋盘分割

棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11938   Accepted: 4207 Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规

【POJ 1191】 棋盘分割(DP)

[POJ 1191] 棋盘分割(DP) Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13811   Accepted: 4917 Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分

(中等) POJ 1191 棋盘分割,DP。

Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行) 原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小. 均方差,其中平均值,xi为第i块矩形棋盘的总分. 请编程对给出的棋盘及n,求出O'的最小值. 题目好像很经典,DP问题,直

poj - 1191 - 棋盘分割(dp)

题意:将一个8*8的棋盘(每个单元正方形有个分值)沿直线(竖或横)割掉一块,留下一块,对留下的这块继续这样操作,总共进行n - 1次,得到n块(1 < n < 15)矩形,每个矩形的分值就是单元正方形的分值的和,问这n个矩形的最小均方差. 题目链接:http://poj.org/problem?id=1191 -->>此题中,均方差比较,等价于方差比较,等价于平方和比较.. 状态:dp[x1][y1][x2][y2][i]表示将(x1, y1)到(x2, y2)的矩形分割i次的最小

POJ 1208.cpp

The Blocks Problem Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4815   Accepted: 2043 Description Many areas of Computer Science use simple, abstract domains for both analytical and empirical studies. For example, an early AI study of

POJ 1191 棋盘分割(DP)

题目链接 题意 : 中文题不详述. 思路 : 黑书上116页讲的很详细.不过你需要在之前预处理一下面积,那样的话之后列式子比较方便一些. 先把均方差那个公式变形, 另X表示x的平均值,两边平方得 平均值是一定的,所以只要让每个矩形的总分的平方和尽量小即可.左上角坐标为(x1,y1)右下角坐标为(x2,y2)的棋盘,设总和为s[][][][],切割k次以后得到k+1块矩形的总分平方和是d[k][][][][],则可以沿着横线切也可以沿着竖线切,然后选一块接着切,递归下去,状态转移方程 d[k,x1

POJ 1191 DP+DFS棋盘分割问题

题目大意: Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘.(每次切割都只能沿着棋盘格子的边进行)原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和.现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小. 均方差,其中平均值,xi为第i块矩形棋盘的总分. 请编程对给出的棋盘及n,求出O'的最小值. 运用动态规划,状态

poj 1191 棋盘切割 (压缩dp+记忆化搜索)

一,题意: 中文题 二.分析: 主要利用压缩dp与记忆化搜索思想 三,代码: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> using namespace std; const int Big=20000000; int Mat[10][10]; int N; int sum[10][10]; int

poj 1191 棋盘分割 (压缩dp+记忆化搜索)

一,题意: 中文题 二,分析: 主要利用压缩dp与记忆化搜索思想 三,代码: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> using namespace std; const int Big=20000000; int Mat[10][10]; int N; int sum[10][10]; int