码迷,mamicode.com
首页 > 其他好文 > 详细

poj1191

时间:2015-06-10 10:10:04      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

http://poj.org/problem?id=1191

棋盘分割
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 12951   Accepted: 4612

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


算法艺术与信息学竞赛上有详细讲解

技术分享
 1 #include <iostream>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6 
 7 const int nMax = 15;
 8 const int size = 9;
 9 const int INF = 100000000;
10 
11 int dp[nMax][size][size][size][size];
12 int sum[size][size];   //左上角为(1,1)的矩形的和
13 
14 int getSum(int x1, int y1, int x2, int y2)
15 {
16     return sum[x2][y2] - sum[x1-1][y2] - sum[x2][y1-1] + sum[x1-1][y1-1];
17 }
18 
19 int cut(int k, int x1, int y1, int x2, int y2)
20 {
21     if(dp[k][x1][y1][x2][y2] != -1)
22     {
23         return dp[k][x1][y1][x2][y2];
24     }
25 
26     if(k == 1)
27     {
28         int t1 = getSum(x1, y1, x2, y2);
29         return (dp[k][x1][y1][x2][y2] = t1*t1);
30     }
31 
32     int minVal = INF, tmp;
33     for(int i = x1; i < x2; ++i)      //纵向切割
34     {
35         int t1 = getSum(x1, y1, i, y2);
36         int t2 = getSum(i+1, y1, x2, y2);
37         tmp = min(cut(k-1, i+1, y1, x2, y2) + t1*t1, cut(k-1, x1, y1, i, y2) + t2*t2);
38         if(minVal > tmp)
39         {
40             minVal = tmp;
41         }
42     }
43 
44     for(int i = y1; i < y2; ++i) //横向切割
45     {
46         int t1 = getSum(x1, y1, x2, i);
47         int t2 = getSum(x1, i+1, x2, y2);
48         tmp = min(cut(k-1, x1, i+1, x2, y2) + t1*t1, cut(k-1, x1, y1, x2, i) + t2*t2);
49         if(minVal > tmp)
50         {
51             minVal = tmp;
52         }
53     }
54 
55     return (dp[k][x1][y1][x2][y2] = minVal);
56 }
57 
58 int main()
59 {
60     int n;
61 
62     memset(dp, -1, sizeof(dp));
63     memset(sum, 0, sizeof(sum));
64 
65     cin>>n;
66     int tot = 0;
67     for(int i = 1; i <= 8; ++i)
68     {
69         for(int j = 1; j <= 8; ++j)
70         {
71             int val;
72             cin>>val;
73             tot += val;
74             sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + val;
75         }
76     }
77 
78     int res = cut(n, 1, 1, size-1, size-1);
79 
80     double avrg = tot*1.0/n;
81     double ans = sqrt(res*1.0/n-avrg*avrg);
82     printf("%.3f\n", ans);
83 
84     return 0;
85 }
View Code

 

poj1191

标签:

原文地址:http://www.cnblogs.com/ygw0616/p/4565221.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!