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;

}

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

【动态规划+递归】:poj1191,棋盘分割

http://poj.org/problem?id=1191 明白几点: 1)最终的均方差可以转变成:sqrt( sigma[ i:1-m ]( xi*xi ) / n - ( sum(al...

POJ1191 棋盘分割

由于题目是中文的,这里就不解释题目大意。是一个很好的dp题目,不过这个题目需要将平方差公式变形,两次运用dp的思想,对中间结果dp。然后的求出最终结果。 #include #include #inc...

poj1191 棋盘分割

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

POJ1191棋盘分割 NYOJ87

另外分享朋友们一起开发的oj:该题地址:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=87/*POJ1191棋盘分隔,刘汝佳黑书面有解析,大概...

POJ 1191 棋盘分割 (记忆化搜索)

题意: 思路:先要对公式化简,我的数学好差,花了好长时间化简。然后用记忆化搜索,dp[d][x1][y1][x2][y2] 存储 把大小为(x1,y1)(x2,y2)的矩阵分成d份的最小值。。 ...

Poj 1191 棋盘分割

题目大意:将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘。(每次切割都只能沿着...

poj 1191 棋盘分割

题目意思,中文不解释: —————————————— 分割线 —————————————— 根据题目的公式可得到,很多东东。 σ=sqrt(((x1-x)^2+(x2-x)^2+.....

poj 1191 棋盘分割

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

棋盘分割 (P1191)

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

poj 1191 棋盘分割 动态规划

棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11457   Accepted...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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