OpenJudge/Poj 1191 棋盘分割

1.链接地址:

http://bailian.openjudge.cn/practice/1191/

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

2.题目:

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

原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。
均方差,其中平均值,xi为第i块矩形棋盘的总分。
请编程对给出的棋盘及n,求出O'的最小值。
输入
第1行为一个整数n(1 < n < 15)。
第2行至第9行每行为8个小于100的非负整数,表示棋盘上相应格子的分值。每行相邻两数之间用一个空格分隔。
输出
仅一个数,为O'(四舍五入精确到小数点后三位)。
样例输入
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
样例输出
1.633
来源
Noi 99

3.思路:

确定公式的常量

深搜+剪枝

4.代码:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 
  5 #define NUM 8
  6 
  7 using namespace std;
  8 
  9 double res_sigma;
 10 
 11 int n;
 12 int arr[NUM][NUM];
 13 
 14 double all_avg;
 15 
 16 double sigma;
 17 
 18 void dfs(int x1,int y1,int x2,int y2,int sum,int cut)
 19 {
 20     int k,i,j;
 21     int temp_sum,temp_avg;
 22     double temp;
 23 
 24     if(cut == 0)
 25     {
 26         temp = (sum - all_avg) * (sum - all_avg);
 27         if(sigma + temp < res_sigma) {res_sigma = sigma + temp;}
 28         return;
 29     }
 30 
 31     temp_sum = 0;
 32     for(k = y1; k < y2; ++k)
 33     {
 34         for(j = x1; j <= x2; ++j) temp_sum += arr[k][j];
 35 
 36         temp_avg = temp_sum;
 37         temp = (all_avg - temp_avg) * (all_avg - temp_avg);
 38         if(sigma + temp < res_sigma) 
 39         {
 40             sigma += temp;
 41             dfs(x1,k + 1,x2,y2,sum - temp_sum,cut - 1);
 42             sigma -= temp;
 43         }
 44 
 45         temp_avg = sum - temp_sum;
 46         temp = (all_avg - temp_avg) * (all_avg - temp_avg);
 47         if(sigma + temp < res_sigma)
 48         {
 49             sigma += temp;
 50             dfs(x1,y1,x2,k,temp_sum,cut - 1);
 51             sigma -= temp;
 52         }
 53         
 54     }
 55 
 56     temp_sum = 0;
 57     for(k = x1; k < x2; ++k)
 58     {
 59         for(i = y1; i <= y2; ++i) temp_sum += arr[i][k];
 60 
 61         temp_avg = temp_sum;
 62         temp = (all_avg - temp_avg) * (all_avg - temp_avg);
 63         if(sigma + temp < res_sigma) 
 64         {
 65             sigma += temp;
 66             dfs(k + 1,y1,x2,y2,sum - temp_sum,cut - 1);
 67             sigma -= temp;
 68         }
 69 
 70         temp_avg = sum - temp_sum;
 71         temp = (temp_avg - all_avg) * (temp_avg - all_avg);
 72         if(sigma + temp < res_sigma)
 73         {
 74             sigma += temp;
 75             dfs(x1,y1,k,y2,temp_sum,cut - 1);
 76             sigma -= temp;
 77         }
 78         
 79     }
 80 }
 81 
 82 int main()
 83 {
 84     //freopen("C://input.txt","r",stdin);
 85 
 86     cin >> n;
 87 
 88 
 89     int i,j;
 90 
 91     int sum = 0;
 92     for(i = 0; i < NUM; ++i)
 93     {
 94         for(j = 0; j < NUM; ++j)
 95         {
 96             cin >> arr[i][j];
 97             sum += arr[i][j];
 98         }
 99     }
100     all_avg = sum * 1.0 / n;
101 
102     res_sigma = sum * sum * n;
103 
104     dfs(0,0,NUM - 1,NUM - 1,sum,n - 1);
105 
106     cout.setf(ios::fixed);
107     cout.precision(3);
108     cout << sqrt(res_sigma / n) << endl;
109 
110     return 0;
111 }
原文地址:https://www.cnblogs.com/mobileliker/p/3570577.html