OpenJudge百炼-1191-棋盘分割-C语言-动态规划
来源:互联网 发布:斗鱼免费刷火箭软件 编辑:程序博客网 时间:2024/05/20 03:39
描述:
将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共有n块矩形棋盘。(每次切割都只能沿着棋盘格子的边进行)
原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。
均方差,其中平均值,xi为第i块矩形棋盘的总分。
请编程对给出的棋盘及n,求出O'的最小值。
输入:
第1行为一个整数n(1 < n < 15)。
第2行至第9行每行为8个小于100的非负整数,表示棋盘上相应格子的分值。每行相邻两数之间用一个空格分隔。
输出:
仅一个数,为O'(四舍五入精确到小数点后三位)。
样例输入:
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
样例输出:
1.633
/*******************************************************文件名:百炼-1191**Copyright (c) 2015-2025 OrdinaryCrazy**创建人:OrdinaryCrazy**日期:20170817**描述:百炼1191参考答案**版本:1.0******************************************************/#include <stdio.h>#include <math.h>int min(int a,int b){ return a > b ? b : a;}/******************************************************这么复杂而没有头绪的题目,当然是要动态规划,首先,怎样模拟棋盘的分割就不是很好做,比较明智的做法就是记录我们现在需要分割的这块板子,是原来棋盘上的哪块区域,上顶y1,下底y2,左边x1,右边x2这样就得到了一组状态,还有一个问题,就是还要切几下这是5个状态,f(x1,x2,y1,y2,k)还有一个问题,这些状态对应的值是什么,直接对应方差好像有点说不通,因为这个值不能递归到子问题去做回到问题我们发现,平均值是整个棋盘的平均值,这个是很好算的,但是要算方差就比较费时了如果直接算的话,频繁的数组操作和复杂的计算必然会导致超时,需要再想办法首先化简一下表达式:@ = 根号(求和((xi - x)^2)/n) = 根号(求和(xi^2 - 2*xi*x + x^2)/n) = 根号((求和(xi^2) - 2*x*求和(xi))/n + x^2) = 根号(求和(xi^2)/n - x^2)好了,我们只需要知道需要计算的所有板子的总分的平方就OK了然而这只是在计算上简单了一点点,数组操作还在,并没有本质上的提高下面想这样一个问题,如果我们知道点(1,1)和(x2,y2)形成的板子的总分那么减掉板(1,1)-(x2,y1-1),(1,1)-(x1-1,y2)再加上板(1,1)-(x1-1,y1-1)的总分就得到了板(x1,y1)-(x2,y2)总分。动态规划,动态规划.jpg*******************************************************/int n,board[9][9],sum[9][9],cost[9][9][9][9][15],inif = 1 << 30;/**cost[x1][y1][x2][y2][k]表示在板(x1,y1)-(x2,y2)上切k次的最小平方和我们最终的目标。就是使cost[1][1][8][8][n-1]达到最小值对于任意一块板子,就有状态递推方程:5种情况:这块板子切了不如不切,从左边切,从右边切,从上边切,从下边切,@为切割点cost[x1][y1][x2][y2][k] = min(cost[x1][y1][x2][y2][k], cost[x1][y1][@][y2][0] + cost[@+1][y1][x2][y2][k-1], cost[x1][y1][@][y2][k-1] + cost[@+1][y1][x2][y2][0], cost[x1][y1][x2][@][0] + cost[x1][@+1][x2][y2][k-1], cost[x1][y1][x2][@][k-1] + cost[x1][@+1][x2][y2][0])**/void count(int x1,int y1,int x2,int y2){ int a = sum[y2][x2] - sum[y1-1][x2] - sum[y2][x1-1] + sum[y1-1][x1-1]; cost[y1][x1][y2][x2][0] = a*a;}int main(){ int i,j,k,x1,x2,y1,y2; scanf("%d",&n); for(i = 1;i < 9;i++) for(j = 1;j < 9;j++) scanf("%d",&board[i][j]); for(i = 1;i < 9;i++) for(j = 1;j < 9;j++) { sum[i][j] = board[i][j] + sum[i - 1][j]; for(k = 1;k < j;k++) sum[i][j] += board[i][k]; } for(y1 = 1;y1 < 9;y1++) for(x1 = 1;x1 < 9;x1++) for(y2 = y1;y2 < 9;y2++) for(x2 = x1;x2 < 9;x2++) count(x1,y1,x2,y2); for(i = 1;i < n;i++) for(y1 = 1;y1 < 9;y1++) for(x1 = 1;x1 < 9;x1++) for(y2 = y1;y2 < 9;y2++) for(x2 = x1;x2 < 9;x2++) { cost[y1][x1][y2][x2][i] = inif; for(k = x1;k < x2;k++) cost[y1][x1][y2][x2][i] = min(cost[y1][x1][y2][x2][i],min(cost[y1][x1][y2][k][0] + cost[y1][k+1][y2][x2][i-1],cost[y1][x1][y2][k][i-1] + cost[y1][k+1][y2][x2][0])); for(k = y1;k < y2;k++) cost[y1][x1][y2][x2][i] = min(cost[y1][x1][y2][x2][i],min(cost[y1][x1][k][x2][0] + cost[k+1][x1][y2][x2][i-1],cost[y1][x1][k][x2][i-1] + cost[k+1][x1][y2][x2][0])); } printf("%.3f",sqrt((double)cost[1][1][8][8][n-1]/n - (double)(sum[8][8]*sum[8][8])/n/n)); return 0;}
阅读全文
0 0
- OpenJudge百炼-1191-棋盘分割-C语言-动态规划
- 棋盘分割 动态规划
- 百炼2791-矩形覆盖-C语言-动态规划
- pku 1191 棋盘分割 (动态规划)
- 动态规划 :POJ 1191 棋盘分割
- 棋盘分割 动态规划 poj 1191
- poj 1191 棋盘分割 动态规划
- 【递归 & 动态规划】POJ 1191 棋盘分割
- POJ-1191-棋盘分割(动态规划)
- OpenJudge百炼 1321 棋盘问题
- POJ1191《棋盘分割》 动态规划
- OpenJudge百炼-2974-487-3279-C语言-字符串处理
- OpenJudge百炼-2744-子串-C语言-字符串处理
- OpenJudge百炼-2712-细菌繁殖-C语言-日期处理
- OpenJudge百炼-2964-日历问题-C语言-日期处理
- OpenJudge百炼-2965-玛雅历-C语言-日期处理
- OpenJudge百炼-2966-时区转换-C语言-日期处理
- OpenJudge百炼-2950-摘花生-C语言
- springmvc的照片上传功能
- java线程面试题
- [shell]截取字符串
- azkaban简单实用
- 聊聊HTTPS和SSL/TLS协议 很精简
- OpenJudge百炼-1191-棋盘分割-C语言-动态规划
- Android中使用ScrollView内嵌ListView出现显示不完全问题
- 《七大排序算法》(Java实现)
- open-falcon 上传数据时间间隔设置1s
- 欢迎使用CSDN-markdown编辑器
- 9 正则表达式
- Codeforces Round #387 (Div. 2) D. Winter Is Coming
- 分布式跟踪系统(一):Zipkin的背景和设计
- 数据库基础知识总结