poj1191 2010.7.31

来源:互联网 发布:linux查看crontab任务 编辑:程序博客网 时间:2024/06/06 23:52

poj1191 2010.7.31

棋盘分割Time Limit: 1000MS  MemoryLimit: 10000K

Total Submissions: 5436  Accepted: 1960

 

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

Source

 

Noi 99

 

 

详见lrj的黑书~~~

 

不过有一个地方要说一下

 

sum[i][j]表示以[1,1],[i,j]为对角的矩阵的和,那么矩阵[x1,y1],[x2,y2]的和为

 

sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1]

 

计算sum[i][j]的时候

 

for(int i=1;i<=M;i++)

{

  for(int j=1;j<=M;j++)

   {

   int value;

   scanf("%d",&value);

   sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+value;

   }

}

 

WA因:把y2打成了y1。。。又是敲错。。。。

 

还有一点要注意的是,刚开始我以为不用递归,用循环嵌套就行了,但是,貌似只用循环是实现不了的。。。还是看了大家的报告才知道要用。。递归。。。。有点像前一段时间的二分dp了。。。

 

Source Code

 

Problem: 1191  User: creamxcream

Memory: 852K  Time: 16MS

Language: C++  Result: Accepted

 

 

Source Code 


#include <cstdio>#include <cstring>#include <cmath>#define MAXN 18#define MAXM 10#define M 8int dp[MAXN][MAXM][MAXM][MAXM][MAXM];int sum[MAXM][MAXM];int n;int min(int a,int b){ if (a<b) return a;else return b;}void init(){ scanf("%d",&n); memset(sum,0,sizeof(sum)); memset(dp,-1,sizeof(dp)); for(int i=1;i<=M;i++) {  for(int j=1;j<=M;j++)  {   int value;   scanf("%d",&value);   sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+value;  } }}int cal(int x1,int y1,int x2,int y2){ int s=(sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1]); return s;}int dpit(int k,int x1,int y1,int x2,int y2){ int t,a,b,c,e,MIN=10000000; if (dp[k][x1][y1][x2][y2]!=-1)  return (dp[k][x1][y1][x2][y2]); if(k==0) {    int t=cal(x1,y1,x2,y2);        dp[k][x1][y1][x2][y2]=t*t;  return t*t; } for(a=x1;a<x2;a++) {  c=cal(a+1,y1,x2,y2);  e=cal(x1,y1,a,y2);  t=min(dpit(k-1,x1,y1,a,y2)+c*c,   dpit(k-1,a+1,y1,x2,y2)+e*e);  if (MIN>t)   MIN=t; } for(b=y1;b<y2;b++) {  c=cal(x1,b+1,x2,y2);  e=cal(x1,y1,x2,b);  t=min(dpit(k-1,x1,y1,x2,b)+c*c,   dpit(k-1,x1,b+1,x2,y2)+e*e);  if (MIN>t)   MIN=t; } dp[k][x1][y1][x2][y2]=MIN; return MIN;}int main(){ init(); int ans; ans=dpit(n-1,1,1,M,M); int s=sum[M][M]*sum[M][M]; ans*=n;ans-=s; double total; total=(double)(ans)/(double)(n*n); printf("%.3lf\n",sqrt(total)); return 0;}


0 0
原创粉丝点击