题目传送门:http://poj.org/problem?id=1191

棋盘分割

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 16150   Accepted: 5768

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

  1. 3
  2. 1 1 1 1 1 1 1 3
  3. 1 1 1 1 1 1 1 1
  4. 1 1 1 1 1 1 1 1
  5. 1 1 1 1 1 1 1 1
  6. 1 1 1 1 1 1 1 1
  7. 1 1 1 1 1 1 1 1
  8. 1 1 1 1 1 1 1 0
  9. 1 1 1 1 1 1 0 3

Sample Output

  1. 1.633

Source

 

题意概括:

中文题,不容小觑。

解题思路:

一、DFS搜索,每次分割棋盘可以选择两个方向 横切(改变Y的范围) 或者 竖切(改变X的范围);选择切割方向之后需要选择舍弃两部分之中的其中一部分,继续DFS另一部分。
二、但单纯的搜索太慢,我们可以发现其实是因为有很多子问题重叠,所以不妨用一个四维数组记录每次小矩形的运算结果,数组下标为小矩阵左上角和右下角的坐标。
三、公式化简:
 
AC code:
  1. ///POJ 1191 棋盘分割 (记忆化搜索经典)
  2. #include <cstdio>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <cstring>
  6. #include <cmath>
  7. #define INF 0x3f3f3f3f
  8. #define ll long long int
  9. #define mod 1000000007
  10. using namespace std;
  11.  
  12. const int MAXN = ;
  13. const int MAXM = ;
  14. double d[MAXN][MAXM][MAXM][MAXM][MAXM];
  15. double record[MAXM][MAXM][MAXM][MAXM];
  16. double mmp[MAXM][MAXM];
  17. double sum, ave;
  18. int N;
  19.  
  20. double get_sum(int x1, int y1, int x2, int y2)
  21. {
  22. if(record[x1][y1][x2][y2]>=) return record[x1][y1][x2][y2];
  23. double re = ;
  24. for(int i = x1; i <= x2; i++)
  25. for(int j = y1; j <= y2; j++)
  26. re+=mmp[i][j];
  27. record[x1][y1][x2][y2] = re*re;
  28. return record[x1][y1][x2][y2];
  29. }
  30.  
  31. double dfs(int x1, int y1, int x2, int y2, int cnt)
  32. {
  33. if(d[cnt][x1][y1][x2][y2]>=) return d[cnt][x1][y1][x2][y2];
  34. if(cnt == N)
  35. {
  36. return get_sum(x1, y1, x2, y2);
  37. }
  38. double min_sum = ;
  39. double tp = ;
  40. for(int i = x1; i < x2; i++)
  41. {
  42. tp = get_sum(x1, y1, i, y2) + dfs(i+, y1, x2, y2, cnt+);
  43. if(min_sum > tp) min_sum = tp;
  44. tp = get_sum(i+, y1, x2, y2) + dfs(x1, y1, i, y2, cnt+);
  45. if(min_sum > tp) min_sum = tp;
  46. }
  47. for(int j = y1; j < y2; j++)
  48. {
  49. tp = get_sum(x1, y1, x2, j) + dfs(x1, j+, x2, y2, cnt+);
  50. if(min_sum > tp) min_sum = tp;
  51. tp = get_sum(x1, j+, x2, y2) + dfs(x1, y1, x2, j, cnt+);
  52. if(min_sum > tp) min_sum = tp;
  53. }
  54. d[cnt][x1][y1][x2][y2] = min_sum;
  55. return min_sum;
  56. }
  57.  
  58. int main()
  59. {
  60. scanf("%d", &N);
  61. memset(d, -, sizeof(d));
  62. memset(record, -, sizeof(record));
  63. for(int i = ; i <= ; i++)
  64. for(int j = ; j <= ; j++)
  65. {
  66. scanf("%lf", &mmp[i][j]);
  67. sum+=mmp[i][j];
  68. }
  69. ave = sum/(N*1.0);
  70. ave*=ave;
  71. double res = dfs(, , , , );
  72. double ans = sqrt(res/N-ave);
  73. printf("%.3f\n", ans);
  74. return ;
  75. }
 
 
 

POJ 1191 棋盘分割 【DFS记忆化搜索经典】的更多相关文章

  1. poj 1191 棋盘分割(dp + 记忆化搜索)

    题目:http://poj.org/problem?id=1191 黑书116页的例题 将方差公式化简之后就是 每一块和的平方 相加/n , 减去平均值的平方. 可以看出来 方差只与 每一块的和的平方 ...

  2. HDU 2517 / POJ 1191 棋盘分割 区间DP / 记忆化搜索

    题目链接: 黑书 P116 HDU 2157 棋盘分割 POJ 1191 棋盘分割 分析:  枚举所有可能的切割方法. 但如果用递归的方法要加上记忆搜索, 不能会超时... 代码: #include& ...

  3. poj 3249(bfs+dp或者记忆化搜索)

    题目链接:http://poj.org/problem?id=3249 思路:dp[i]表示到点i的最大收益,初始化为-inf,然后从入度为0点开始bfs就可以了,一开始一直TLE,然后优化了好久才4 ...

  4. 不要62 hdu 2089 dfs记忆化搜索

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2089 题意: 给你两个数作为一个闭区间的端点,求出该区间中不包含数字4和62的数的个数 思路: 数位dp中 ...

  5. dfs+记忆化搜索,求任意两点之间的最长路径

    C.Coolest Ski Route 题意:n个点,m条边组成的有向图,求任意两点之间的最长路径 dfs记忆化搜索 #include<iostream> #include<stri ...

  6. POJ 2704 Pascal's Travels 【DFS记忆化搜索】

    题目传送门:http://poj.org/problem?id=2704 Pascal's Travels Time Limit: 1000MS   Memory Limit: 65536K Tota ...

  7. POJ 1088 滑雪 DFS 记忆化搜索

    http://poj.org/problem?id=1088 校运会放假继续来水一发^ ^ 不过又要各种复习,功课拉下了许多 QAQ. 还有呀,就是昨天被一个学姐教育了一番,太感谢了,嘻嘻^ ^ 好了 ...

  8. poj1088-滑雪 【dfs 记忆化搜索】

    http://poj.org/problem?id=1088 滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 79806 ...

  9. BZOJ1048:[HAOI2007]分割矩阵(记忆化搜索DP)

    Description 将一个a*b的数字矩阵进行如下分割:将原矩阵沿某一条直线分割成两个矩阵,再将生成的两个矩阵继续如此分割(当然也可以只分割其中的一个), 这样分割了(n-1)次后,原矩阵被分割成 ...

随机推荐

  1. java中构造函数的特点

    构造函数的名字必须和类名完全相同,构造函数不能有 返回值,就是void 也不要写,构造函数不可以被子类继承 构造函数可以重载但是不可以被子类覆盖. 简单的例子 class A{ A(){ } A(in ...

  2. 案例43-crm练习获取客户列表使用struts2

    1 src下配置文件 1 struts.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYP ...

  3. Unity3D之OnGUI知识总结

    相对位置参考   http://blog.csdn.net/sunny__chen/article/details/51323265 自适应屏幕收缩  http://www.360doc.com/co ...

  4. Java入门系列-09-循环结构

    这篇文章为你搞懂5个问题 while 循环如何使用 do-while 循环的使用 for 循环的使用 break.continue 的使用 循环结构的嵌套使用 生活中有很多事情需要我们重复的去做,比如 ...

  5. HDU 1257——最少拦截系统——————【LIS变型题】

    最少拦截系统 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  6. js event事件绑定的方法

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  7. js获取当前日期,格式为YYYY-MM-DD

    //获取当前时间,格式YYYY-MM-DD function getNowFormatDate() { var date = new Date(); var seperator1 = "-& ...

  8. java 获取网络地址图片

    收藏一个获取网络图片的方法. //获取网络图片 public void ImageRequest(String ImageName,String GifUrl) throws Exception { ...

  9. Spring.NET入门

    Spring.NET入门  http://www.cnblogs.com/haogj/archive/2011/06/10/2077540.html http://www.cnblogs.com/ha ...

  10. Promise/A+规范学习总结

    Promise的实现:因为他只是一个规范,所以在不同的框架或者平台下有不同的实现 Angular:$q服务 Node:q模块,co,then Es6:Promise, yield Es7:async ...