您的位置:首页 > 运维架构

OpenJudge/Poj 1191 棋盘分割

2014-02-27 03:07 471 查看
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.代码:

#include <iostream>
#include <cstdio>
#include <cmath>

#define NUM 8

using namespace std;

double res_sigma;

int n;
int arr[NUM][NUM];

double all_avg;

double sigma;

void dfs(int x1,int y1,int x2,int y2,int sum,int cut)
{
int k,i,j;
int temp_sum,temp_avg;
double temp;

if(cut == 0)
{
temp = (sum - all_avg) * (sum - all_avg);
if(sigma + temp < res_sigma) {res_sigma = sigma + temp;}
return;
}

temp_sum = 0;
for(k = y1; k < y2; ++k)
{
for(j = x1; j <= x2; ++j) temp_sum += arr[k][j];

temp_avg = temp_sum;
temp = (all_avg - temp_avg) * (all_avg - temp_avg);
if(sigma + temp < res_sigma)
{
sigma += temp;
dfs(x1,k + 1,x2,y2,sum - temp_sum,cut - 1);
sigma -= temp;
}

temp_avg = sum - temp_sum;
temp = (all_avg - temp_avg) * (all_avg - temp_avg);
if(sigma + temp < res_sigma)
{
sigma += temp;
dfs(x1,y1,x2,k,temp_sum,cut - 1);
sigma -= temp;
}

}

temp_sum = 0;
for(k = x1; k < x2; ++k)
{
for(i = y1; i <= y2; ++i) temp_sum += arr[i][k];

temp_avg = temp_sum;
temp = (all_avg - temp_avg) * (all_avg - temp_avg);
if(sigma + temp < res_sigma)
{
sigma += temp;
dfs(k + 1,y1,x2,y2,sum - temp_sum,cut - 1);
sigma -= temp;
}

temp_avg = sum - temp_sum;
temp = (temp_avg - all_avg) * (temp_avg - all_avg);
if(sigma + temp < res_sigma)
{
sigma += temp;
dfs(x1,y1,k,y2,temp_sum,cut - 1);
sigma -= temp;
}

}
}

int main()
{
//freopen("C://input.txt","r",stdin);

cin >> n;

int i,j;

int sum = 0;
for(i = 0; i < NUM; ++i)
{
for(j = 0; j < NUM; ++j)
{
cin >> arr[i][j];
sum += arr[i][j];
}
}
all_avg = sum * 1.0 / n;

res_sigma = sum * sum * n;

dfs(0,0,NUM - 1,NUM - 1,sum,n - 1);

cout.setf(ios::fixed);
cout.precision(3);
cout << sqrt(res_sigma / n) << endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: