将一个8*8的棋盘进行如下分割:
将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,
再将剩下的部分继续如此分割, 这样割了(n-1)次后,
连同最后剩下的矩形棋盘共有n块矩形棋盘.
(每次切割都只能沿着棋盘格子的边进行)
允许的分割方案 2
不允许的分割方案 原棋盘上每一格有一个分值,
一块矩形棋盘的总分为其所含各格分值之和
现在需要把棋盘按上述规则分割成 n 块矩形棋盘,
并使各矩形棋盘总分的均方差最小
均方差 , 其中平均值 ,
xi 为第 i 块矩形棋盘的总分
请编程对给出的棋盘及 n, 求出 σ 的最小值
第1行为一个整数n (1 < n < 15)
第2行至第9行每行为8个小于100的非负整数, 表示棋盘上
相应格子的分值
每行相邻两数之间用一个空格分隔
输出
仅一个数, 为σ (四舍五入精确到小数点后三位)
4 样例输入
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
样例输出
//
这个题和以前做过的挑战程序设计里面的分棒子差不多,都是递归的解决问题,不算很难。
/
#include<iostream>
#include<iomanip>using namespace std;
const int maxNum = 9;
double getResult(int n,int x1,int y1,int x2,int y2);
int tmpresult[15][maxNum][maxNum][maxNum][maxNum];
int board[maxNum][maxNum];
int gradeSum[maxNum][maxNum];
int calSum(int x1,int y1,int x2,int y2);
int main(){
memset(tmpresult,-1,sizeof(tmpresult));
memset(gradeSum,0,sizeof(gradeSum));
int n;
cin>>n;
for(int i = 1;i <= 8;i++)
{
int lineSum(0);
for(int j = 1;j <= 8;j++)
{
cin>>board[i][j];
lineSum += board[i][j];
gradeSum[i][j] = gradeSum[i - 1][j] + lineSum;//gradeSum数组用来储存每个格子的分数
}
}
double result = n*getResult(n,1,1,8,8)-gradeSum[8][8]*gradeSum[8][8];
cout<<setiosflags(ios::fixed)<<setprecision(3)<<sqrt(result/(n*n))<<endl;
return 0;
}
int calSum(int x1,int y1,int x2,int y2){
return gradeSum[x2][y2]-gradeSum[x1 - 1][y2]-gradeSum[x2][y1 - 1]+gradeSum[x1][y1];
}
double getResult(int n,int x1,int y1,int x2,int y2){
int minNum(10000);
int t,s1,s2,line,vertical;
if(tmpresult[n][x1][y1][x2][y2] != -1)
return tmpresult[n][x1][y1][x2][y2];
if(n == 1)
{
t = calSum(x1,y1,x2,y2);
tmpresult[n][x1][y1][x2][y2] = t * t;
return t * t;
}
for(vertical = x1;vertical < x2;line++)
{
s1 = calSum(x1,y1,vertical,y2);
s2 = calSum(vertical+1,y1,x2,y2);
t = min((getResult(n-1,x1,y1,vertical,y2)+s2 * s2),(getResult(n-1,vertical+1,y1,x2,y2)+s1 * s1));
if(t < minNum)
minNum = t;
}
for(line = y1;line < y2;line++)
{
s1 = calSum(x1,y1,x2,line);
s2 = calSum(x1,line + 1,x2,y2);
t = min((getResult(n - 1,x1,y1,x2,line)+s2 * s2),(getResult(n - 1,x1,line + 1,x2,y2)+s1 * s1));
if(t < minNum)
minNum = t;
}
tmpresult[n][x1][y1][x2][y2] = minNum;
return minNum;
}