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 }