棋盘分割问题

题目大意,将一个棋盘分割成k-1个矩形,每个矩形都对应一个权值,让所有的权值最小求分法

很像区间DP,但是也不能说就是

我们只要想好了一个怎么变成两个,剩下的就好了,但是怎么变,就是变化的必要条件是什么

k——分割的个数肯定是必须的,而表示一个矩形,至少要知道两个点,所以x1,y1,x2,y2也是必须的,So,五维的DP,以前想都不敢想啊

dp[k][x1][y1][x2][y2]

先不来说他的值如何计算,先来看看如何分割

根据区间DP的思想

dp[k][x1][y1][x2][y2]

  如果横向分割就会有一个状态 dp[k-1][x1][y1][x2][t] + dp[0][x1][t+1][x2][y2]

                dp[0][x1][y1][x2][t] + dp[k-1][x1][t+1][x2][y2]

  相对应竖向呢就会有     dp[k-1][x1][y1][t][y2] + dp[0][t+1][y1][x2][y2]

                dp[0][x1][y1][t][y2] + dp[k-1][t+1][y1][x2][y2]

这就是状态转移的方程

最后就是权值的问题了

对方差公式进行化解,得到σ^2=1/n∑xi^2 - x^2

可知,要使方差最小,只需使∑xi^2最小即可,即各块分值平方和最小。平均值 x是个固定的数,跟分割的方式没有关系,

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string.h>
#include <iomanip>
using namespace std;
int data[9][9];
int sum[9][9];
double dp[14][9][9][9][9]; double get_count(int x1,int y1,int x2,int y2)
{
double ans = double(sum[x2][y2] - sum[x1-1][y2]-sum[x2][y1-1] + sum[x1-1][y1-1]); return ans * ans;
}
int main()
{
int n,total = 0;
scanf("%d",&n);
for(int i = 1;i <= 8;i++)
{
for(int j = 1;j <= 8;j++)
{
cin>>data[i][j];
//sum[i][j]表示棋盘(1,1)到(i,j)区域的累计分值
sum[i][j] = sum[i][j-1] + sum[i-1][j] - sum[i-1][j-1] + data[i][j];
//total表示整个棋盘的分值之和
total += data[i][j];
}
} for(int x1 = 1;x1 <= 8;x1++)
{
for(int y1 = 1;y1 <= 8;y1++)
{
for(int x2 = x1;x2 <= 8;x2++)
{
for(int y2 = y1;y2 <= 8;y2++)
{
dp[0][x1][y1][x2][y2] = get_count(x1,y1,x2,y2);
}
}
}
}
for(int k = 1;k < n;k++)
{
for(int x1 = 1;x1 <= 8;x1++)
{
for(int y1 = 1;y1 <= 8;y1++)
{
for(int x2 = x1;x2 <= 8;x2++)
{
for(int y2 = y1;y2 <= 8;y2++)
{
int t;
dp[k][x1][y1][x2][y2] = (double)(1 << 30);
for(t = x1;t < x2;t++)
{
dp[k][x1][y1][x2][y2] = min(dp[k][x1][y1][x2][y2],dp[0][x1][y1][t][y2] + dp[k-1][t+1][y1][x2][y2]);
dp[k][x1][y1][x2][y2] = min(dp[k][x1][y1][x2][y2],dp[k-1][x1][y1][t][y2] + dp[0][t+1][y1][x2][y2]);
} for(t = y1;t < y2;t++)
{
dp[k][x1][y1][x2][y2] = min(dp[k][x1][y1][x2][y2],dp[0][x1][y1][x2][t] + dp[k-1][x1][t+1][x2][y2]);
dp[k][x1][y1][x2][y2] = min(dp[k][x1][y1][x2][y2],dp[k-1][x1][y1][x2][t] + dp[0][x1][t+1][x2][y2]);
}
}
}
}
}
}
double ans = dp[n-1][1][1][8][8] * 1.0 / n - ((double)total*1.0/n)*((double)total*1.0/n);
//printf("%d %.3lf\n",total,dp[n-1][1][1][8][8]);
printf("%.3lf\n",sqrt(ans));
return 0;
}

POJ 1191棋盘分割问题的更多相关文章

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

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

  2. POJ 1191 棋盘分割 【DFS记忆化搜索经典】

    题目传送门:http://poj.org/problem?id=1191 棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submission ...

  3. poj 1191 棋盘分割 动态规划

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

  4. POJ 1191 棋盘分割

    棋盘分割 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 11213 Accepted: 3951 Description 将一个 ...

  5. OpenJudge/Poj 1191 棋盘分割

    1.链接地址: http://bailian.openjudge.cn/practice/1191/ http://poj.org/problem?id=1191 2.题目: 总时间限制: 1000m ...

  6. (中等) POJ 1191 棋盘分割,DP。

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

  7. POJ - 1191 棋盘分割 记忆递归 搜索dp+数学

    http://poj.org/problem?id=1191 题意:中文题. 题解: 1.关于切割的模拟,用递归 有这样的递归方程(dp方程):f(n,棋盘)=f(n-1,待割的棋盘)+f(1,割下的 ...

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

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

  9. POJ 1191 棋盘分割(DP)

    题目链接 题意 : 中文题不详述. 思路 : 黑书上116页讲的很详细.不过你需要在之前预处理一下面积,那样的话之后列式子比较方便一些. 先把均方差那个公式变形, 另X表示x的平均值,两边平方得 平均 ...

随机推荐

  1. PAT 1031 查验身份证(15)(C++&Python)

    1031 查验身份证(15)(15 分) 一个合法的身份证号码由17位地区.日期编号和顺序编号加1位校验码组成.校验码的计算规则如下: 首先对前17位数字加权求和,权重分配为:{7,9,10,5,8, ...

  2. 文档根元素 "mapper" 必须匹配 DOCTYPE 根 "configuration"

    该问题是因为xml的头部写错了,一个是configuration,一个是mapper,不能直接复制. 参考链接:http://blog.csdn.net/testcs_dn/article/detai ...

  3. python实现文件下载图片视频

    最近在学习爬虫,在爬取网站时很多时候是需要将图片或视频下载到本地 今天就来说说如何使用urllib将图片保存到本地 以下代码均为win7  python3.6.* 方法一(使用下载函数保存) from ...

  4. web前端学习笔记:文本属性

    今天的web前端笔记主要讲述文本属性,希望能帮助到正在学习web前端开发的初学者们,废话不多说了,一起来看看文本属性的相关内容吧. 文本属性 文本缩进 将Web页面上的一个段落第一行缩进,这是一种最常 ...

  5. BZOJ 1791: [IOI2008]Island 岛屿 - 基环树

    传送门 题解 题意 = 找出无向基环树森林的每颗基环树的直径. 我们首先需要找到每颗基环树的环, 但是因为是无向图,用tarjan找环, 加个手工栈, 我也是看了dalao的博客才知道tarjan找无 ...

  6. pycharm和anaconda

    借鉴其他博文和亲自操作做一简要的总结: anaconda是python中一个管理包很好用的工具,可以轻松实现python中的各种包的管理.相信大家会有这样的体验,在pycharm中也是有自动搜索和下载 ...

  7. 虚函数与bind 实现设计模式的练习

    相同模式使用虚函数与bind function进行实现对比 #include "stdafx.h" #include <iostream> #include <f ...

  8. 事务ACID如何定义,事务隔离性解决的问题

    挚享科技 2018.4.8 事务的四个特性: 1. 原子性: 同一个事务的多个操作,要么都成功,要么全部失败回滚. 2. 一致性: 事务必须确保数据库从一个一致性状态变换为另一个一致性状态. 其实就是 ...

  9. 【UI测试】--快捷键组合

  10. Linux学习笔记:Jenkins的使用

    在windows中使用Jenkins(Linux系统下类似),步骤是: 1 从官网下载jenkins项目的war包 2 将jenkins.war放到tomcat的webapps目录中,启动tomcat ...