poj1191 棋盘分割【区间DP】【记忆化搜索】
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 16263 | Accepted: 5812 |
Description

原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的均方差最小。
均方差
请编程对给出的棋盘及n,求出O'的最小值。
Input
第2行至第9行每行为8个小于100的非负整数,表示棋盘上相应格子的分值。每行相邻两数之间用一个空格分隔。
Output
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
题意:
一个8*8的棋盘,进行分割。每次将一个矩形分割成两个。一个矩形的值是里面所有格子值之和。现在想切出n个矩形,希望求得最小的均方差。
思路:
我们先把均方差的公式进行化简
平均值是一个定值,因为每个矩形都是格子值之和。于是我们发现结果之和Xi平方有关。Xi平方越小越好。
对于每一个格子,都可以用两个坐标(i, j)和(x,y)表示,他们分别是矩形的左上角和右下角。
一个矩形有两种切割方法,横着切,竖着切,假设在k处切
横着切时,矩形被分成了(i, j)(k, y) 和 (k + 1, j)(x,y)
竖着切时,矩形被分成了(i,j)(x,k) 和(i, k+1)(x,y)
但是这样还没办法进行状态转移,因为矩形的先后顺序不知道。所以我们可以再引入一维变量,表示各自的顺序。
于是在切割i次时,得到两个矩形,其中一个应该是i+1次切割的矩形。可以得到状态转移方程。
因为是i推i+1,所以用记忆化搜索写起来可能方便一点
- //#include <bits/stdc++.h>
- #include<iostream>
- #include<cmath>
- #include<algorithm>
- #include<stdio.h>
- #include<cstring>
- #include<vector>
- #include<map>
- #include<set>
- #define inf 0x3f3f3f3f
- using namespace std;
- typedef long long LL;
- int n;
- int board[][], hang[][], dp[][][][][];
- /*int getval(int i, int j, int x, int y)
- {
- int res = 0;
- for(int k = i; k <= x; k++){
- res += hang[i][y] - hang[i][j - 1];
- }
- return res * res;
- }*/
- int getval(int i, int j, int x, int y)
- {
- int res = ;
- for(int a = i; a <= x; a++){
- for(int b = j; b <= y; b++){
- res += board[a][b];
- }
- }
- return res * res;
- }
- int DP(int k, int i, int j, int x, int y)
- {
- int ans = ;
- if(dp[k][i][j][x][y] >= )return dp[k][i][j][x][y];
- if(k == n - ){
- return getval(i, j, x, y);
- }
- dp[k][i][j][x][y] = inf;
- for(int tmp = i; tmp < x; tmp++){
- ans = min(DP(k + , i, j, tmp, y) + getval(tmp + , j, x, y), DP(k + , tmp + , j, x, y) + getval(i, j, tmp, y));
- dp[k][i][j][x][y] = min(ans, dp[k][i][j][x][y]);
- }
- for(int tmp = j; tmp < y; tmp++){
- ans = min(DP(k + , i, j, x, tmp) + getval(i, tmp + , x, y), DP(k + , i, tmp + , x, y) + getval(i, j, x, tmp));
- dp[k][i][j][x][y] = min(ans, dp[k][i][j][x][y]);
- }
- return dp[k][i][j][x][y];
- }
- int main(){
- while(scanf("%d", &n) != EOF){
- double sum = ;
- memset(hang, , sizeof(hang));
- for(int i = ; i <= ; i++){
- for(int j = ; j <= ; j++){
- scanf("%d", &board[i][j]);
- sum += board[i][j] * 1.0;
- hang[i][j] = hang[i][j - ] + board[i][j];
- }
- }
- sum /= 1.0 * n;
- memset(dp, -, sizeof(dp));
- int ans = DP(, , , , );
- //cout<<ans<<endl;
- //cout<<dp[n - 1][1][1][8][8]<<endl;
- printf("%.3f\n",sqrt((dp[][][][][])*1.0/n-sum*sum));
- }
- return ;
- }
poj1191 棋盘分割【区间DP】【记忆化搜索】的更多相关文章
- HDU 2517 / POJ 1191 棋盘分割 区间DP / 记忆化搜索
题目链接: 黑书 P116 HDU 2157 棋盘分割 POJ 1191 棋盘分割 分析: 枚举所有可能的切割方法. 但如果用递归的方法要加上记忆搜索, 不能会超时... 代码: #include& ...
- (区间dp + 记忆化搜索)Treats for the Cows (POJ 3186)
http://poj.org/problem?id=3186 Description FJ has purchased N (1 <= N <= 2000) yummy treats ...
- POJ 1191 棋盘分割 【DFS记忆化搜索经典】
题目传送门:http://poj.org/problem?id=1191 棋盘分割 Time Limit: 1000MS Memory Limit: 10000K Total Submission ...
- UVA 10003 Cutting Sticks 区间DP+记忆化搜索
UVA 10003 Cutting Sticks+区间DP 纵有疾风起 题目大意 有一个长为L的木棍,木棍中间有n个切点.每次切割的费用为当前木棍的长度.求切割木棍的最小费用 输入输出 第一行是木棍的 ...
- uva 10891 区间dp+记忆化搜索
https://vjudge.net/problem/UVA-10891 给定一个序列x,A和B依次取数,规则是每次只能从头或者尾部取走若干个数,A和B采取的策略使得自己取出的数尽量和最大,A是先手, ...
- poj1191棋盘分割——区间DP
题目:http://poj.org/problem?id=1191 分析题意,可知每次要沿棋盘中的一条线把一块一分为二,取其中一块继续分割: σ最小经分析可知即为每块的xi和的平方最小: 故用区间DP ...
- loj 1031(区间dp+记忆化搜索)
题目链接:http://lightoj.com/volume_showproblem.php?problem=1031 思路:dp[i][j]表示从区间i-j中能取得的最大值,然后就是枚举分割点了. ...
- BZOJ1055[HAOI2008]玩具取名 【区间dp + 记忆化搜索】
题目 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后 他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使得自己的名字能够 ...
- hdu 4597 Play Game(区间dp,记忆化搜索)
Problem Description Alice and Bob are playing a game. There are two piles of cards. There are N card ...
- poj 1088 滑雪(区间dp+记忆化搜索)
题目链接:http://poj.org/problem?id=1088 思路分析: 1>状态定义:状态dp[i][j]表示在位置map[i][j]可以滑雪的最长区域长度: 2>状态转移方程 ...
随机推荐
- 【复杂】CentOS 6.4下PXE+Kickstart无人值守安装操作系统
一.简介 1.1 什么是PXE PXE(Pre-boot Execution Environment,预启动执行环境)是由Intel公司开发的最新技术,工作于Client/Server的网络模式,支持 ...
- Shader开发之三大着色器
固定功能管线着色器Fixed Function Shaders 固定功能管线着色器的关键代码一般都在Pass的材质设置Material{}和纹理设置SetTexture{}部分. Shader &qu ...
- 【Mongo】聚合函数
http://blog.csdn.net/miyatang/article/details/20997313 SQL Terms, Functions, and Concepts MongoDB Ag ...
- 使用Visual Studio将C#生成DLL文件的方法
1.命令方式 打开Visual Studio安装目录下的开发人员命令提示 译 File.cs 以产生 File.exe csc File.cs 编译 File.cs 以产生 File.dll csc ...
- 数据挖掘Apriori算法——学习笔记
关联规则.频繁项集.支持度.置信度 关联规则挖掘: 一起购买的商品 支持度(support) 支持度会随着物品增多而减小.因为是同时购买的比率. 置信度(Confidence) 频繁且强规则,有一定意 ...
- Visual Studio 2013 离线版msdn下载和安装
Visual Studio 2013出来后,并没有自带msdn安装包,而变成了在线安装msdn,好处是msdn可以随时进行更新,坏处是难道以后每次重新安装系统,都需要重新下载吗,如何解决这个问题呢?本 ...
- linux,shell脚本中获取脚本的名字,使用脚本的名字。
需求描述: 写shell脚本的过程中,有时会需要获取脚本的名字,比如,有的时候,脚本 中会有usage()这种函数,可能就会用到脚本的名字. 实现方法: shell脚本中,通过使用$0就可以获取到脚本 ...
- ubuntu网页无法看视频
sudo apt-get install flashplugin-nonfree sudo apt-get install aptitude sudo aptitude install ubuntu- ...
- laravel 模版赋值
1)一般赋值是直接用view助手函数返回的 return view('Index/index', ['key'=>'value']); 2)一般做系统时,我们都会有一个共同控制器,其他控制器继承 ...
- scala函数进阶篇
1.求值策略scala里有两种求值策略Call By Value -先对函数实参求值,在函数体中用这个求出的参数值.Call By Name -先不对函数实参求值,而是函数实参每次在函数体内被用到时都 ...