1191 棋盘分割

原创 2011年01月24日 12:50:00

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

 

 

刘汝佳黑书上有证明,先化简了求解公式,最后直接关联到xi2(i=1,2,3…,n)。

看了好久,起初被五维数组吓到了。

后来想了一下,记录主要是为了避免TLE而已。

递归的思想,n==2的情况来想,就容易很多了^ ^

附上书上的截图

//pku poj 1191 棋盘分割

#include<iostream>

#include<math.h>

double d[10][10][10][10][20]; //记录状态

double     s[10][10][10][10]; //记录每一块的和

double map[10][10];

double MY_min(double a,double b)  //比较函数

{

      return a<b ? a : b ;

}

double sum_area(int i1,int j1,int i2,int j2) //计算每一块的和

{

      if(s[i1][j1][i2][j2]>=0)      //这一步避免重复计算

            return s[i1][j1][i2][j2];

      int i,j;

      double sum=0;

      for(i=i1;i<=i2;i++)

      {

           for(j=j1;j<=j2;j++)

           {

                 sum+=map[i][j];

           }

      }

      s[i1][j1][i2][j2]=sum*sum; //预先平方

      return s[i1][j1][i2][j2];

}

double calculate(int i1,int j1,int i2,int j2,int n)

{

      if(d[i1][j1][i2][j2][n]>=0)

           return d[i1][j1][i2][j2][n];

      if(n==1)

           return s[i1][j1][i2][j2];

      double mini=99999999999;

      double temp_min;

      int i,j;

 

      //下面这两个循环判断横切还是竖切

      for(i=i1;i<i2;i++) //判断横切是取上半部分还是下半部分

      {

           temp_min=MY_min( calculate(i1,j1,i,j2,n-1)+sum_area(i+1,j1,i2,j2) ,  calculate(i+1,j1,i2,j2,n-1)+sum_area(i1,j1,i,j2)  );

           if(temp_min<mini)

                 mini=temp_min;

      }

      for(j=j1;j<j2;j++) //判断竖切是取左半部分还是右半部分

      {

           temp_min=MY_min( calculate(i1,j1,i2,j,n-1)+sum_area(i1,j+1,i2,j2) ,  calculate(i1,j+1,i2,j2,n-1)+sum_area(i1,j1,i2,j)  );

           if(temp_min<mini)

                 mini=temp_min;

      }

      d[i1][j1][i2][j2][n]=mini;//保存状态

      return d[i1][j1][i2][j2][n];

}

int main()

{

      int n;

      int i,j;

      double sum=0;

      double mini;

      scanf("%d",&n);

      for(i=1;i<=8;i++)

      {

           for(j=1;j<=8;j++)

           {

                 scanf("%lf",&map[i][j]);

                 sum+=map[i][j];

           }

      }

 

      //两个数组都先初始化为-1,方便之后每一次判断避免重复运算

      memset(d,-1,sizeof(d));

      memset(s,-1,sizeof(s));

 

      mini=calculate(1,1,8,8,n);

     

      sum/=(n*1.0);

      printf("%.3lf/n",sqrt(mini/(n*1.00)-(sum*sum)));

      return 0;

}

 

棋盘分割 (P1191)

自己做出来的有一点问题,不过还算是过了。 #include #include #include #include #include #include #include #include #i...

POJ1191--棋盘分割--DP

Description 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘。(每...
  • a305657
  • a305657
  • 2013年04月05日 10:05
  • 585

洛谷 P1436 POJ 1191 [NOI1999 D1T2] 棋盘分割

动态规划+数论

poj 1191 棋盘分割 记忆化搜索

纠结了一天,奇葩的代码,dp初始化的时候,用memset(dp, 0x3f, sizeof(dp)),记忆化搜索判断用 if( dp[tim][x1][y1][x2][y2] == 0x3f3f3f3...

【NOI1999】poj1191 棋盘分割

动态规划
  • sdfzyhx
  • sdfzyhx
  • 2016年07月26日 21:53
  • 365

poj 1191 棋盘分割

黑书例题,上午写了写。黑书上讲的很清楚,经化简,只需求得切割后每个矩形的总分的平方和最小即可。然后可以横切和竖切,枚举切的位置即可。初始化s中存的是x1 y1 到 x2 y2的和的平方,这个可以直接循...

[DP+记忆化搜索]poj1191 棋盘分割

题意: 把棋盘切割成n份,但是要按照规则,不管横切竖切要一刀贯穿,所以并不是普通的切割,求切割后各矩形棋盘总分的最小均方差 思路: 肯定要把看着繁复的均方差公式简化,由于根号、除以n、x平均值(...

poj 1191 棋盘分割 动态规划

棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11457   Accepted...

poj 1191 棋盘分割

棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10807   Accepted...
  • WEYuLi
  • WEYuLi
  • 2013年06月19日 16:35
  • 673

POJ--1191[棋盘分割] 记忆化搜索

思路:(具体参考《算法艺术与信息学竞赛》) 1,先化简均方差公式,可以看出,只需要让每个分割后的矩形的总分的平方和尽量小,即可使均方差最小。 2,考虑左上角坐标为(x1,y1),右下角坐标为(x2...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:1191 棋盘分割
举报原因:
原因补充:

(最多只允许输入30个字)