COGS 100. [NOI1999] 棋盘分割

http://www.cogs.pro/cogs/problem/problem.php?pid=100

★★   输入文件:division.in   输出文件:division.out   简单对比
时间限制:1 s   内存限制:128 MB

【问题描述】
  将一个8×8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将分割过的部分任选一块继续如此分割,这样割了n-1次后,连同最后剩下的矩形棋盘共有n块矩形棋盘。(每次切割都只能沿着棋盘格子的边进行)

    原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。现在需要把棋盘按上述规则分割成 n 块矩形棋盘,并使各矩形棋盘总分的均方差最小。
均方差 ,其中平均值 x i 为第 i 块矩形棋盘的分。
请编程对给出的棋盘及 n ,求出 的最小值。
 
【输入格式】
第 1 行为一个整数 n(1<n<9) 。<="" div="">

第 2 行至第 9 行每行为 8 个小于 100 的非负整数,表示棋盘上相应格子的分值。每行相邻两数之间用一个空格分隔。

【输出格式】
   
仅一个数,为 (四舍五入精确到小数点后三位)。
【输入样例】
输入文件名:division.in

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
输出文件名:division.out
1.633
注意合法的切割方案是指 切了一刀后,选其中一块继续切,另一块不能再切
首先将均方差公式变形
 
第三个等号到第四个等号的变换:
 
平均值固定不变,所以只需最小化每个矩形总分的平方和
dp[k][x1][x2][y1][y2] 矩形左上角标号为(x1,y2) ,右上角标号为(x2,y2),分为k个矩形 所得到的最小平方和
初始化:dp 极大值
预处理:s[x1][x2][y1][y2]   矩形左上角标号为(x1,y2) ,右上角标号为(x2,y2)内所有数和的平方
          dp[1][x1][x2][y1][y2]=s[x1][x2][y1][y2] (相当于一刀也不切的情况)
状态转移:dp[k][x1][y1][x2][y2]=min(
             dp[k-1][x1][y1][x][y2]+s[x+1][y1][x2][y2]) //横着切,取上面一部分继续切
             dp[k-1][x+1][y1][x2][y2]+s[x1][y1][x][y2]//横着切,取下面一部分继续切
             dp[k-1][x1][y1][x2][y]+s[x1][y+1][x2][y2]//竖着切,取左边一部分继续切 
             dp[k-1][x1][y+1][x2][y2]+s[x1][y1][x2][y] //竖着切,取右边一部分继续切
)
转移过程可用记忆化搜索实现

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 1e9
using namespace std;
int n,a[][],dp[][][][][],s[][][][];
int add(int x1,int y1,int x2,int y2)
{
int tmp=;
for(int i=x1;i<=x2;i++)
for(int j=y1;j<=y2;j++)
tmp+=a[i][j];
return tmp;
}
int dfs(int k,int x1,int y1,int x2,int y2)
{
if(dp[k][x1][y1][x2][y2]!=INF) return dp[k][x1][y1][x2][y2];
if(x2>x1)
{
for(int i=x1;i<x2;i++)
{
int t1=dfs(k-,x1,y1,i,y2),t2=dfs(k-,i+,y1,x2,y2);
int t=min(t1+s[i+][y1][x2][y2],t2+s[x1][y1][i][y2]);
dp[k][x1][y1][x2][y2]=min(dp[k][x1][y1][x2][y2],t);
}
}
if(y2>y1)
{
for(int i=y1;i<y2;i++)
{
int t1=dfs(k-,x1,y1,x2,i),t2=dfs(k-,x1,i+,x2,y2);
int t=min(t1+s[x1][i+][x2][y2],t2+s[x1][y1][x2][i]);
dp[k][x1][y1][x2][y2]=min(dp[k][x1][y1][x2][y2],t);
}
}
return dp[k][x1][y1][x2][y2];
}
int main()
{
/*freopen("division.in","r",stdin);
freopen("division.out","w",stdout);*/
scanf("%d",&n);
for(int i=;i<=;i++)
for(int j=;j<=;j++)
scanf("%d",&a[i][j]);
for(int k=;k<=n;k++)
for(int x1=;x1<=;x1++)
for(int y1=;y1<=;y1++)
for(int x2=;x2<=;x2++)
for(int y2=;y2<=;y2++)
dp[k][x1][y1][x2][y2]=INF;
for(int x1=;x1<=;x1++)
for(int y1=;y1<=;y1++)
for(int x2=;x2<=;x2++)
for(int y2=;y2<=;y2++)
{
int tmp=add(x1,x2,y1,y2);
dp[][x1][x2][y1][y2]=s[x1][x2][y1][y2]=tmp*tmp;
}
int tmp=dfs(n,,,,);
int px=add(,,,);
double t=((double) (px) / n )*((double) (px) / n );
double r= (double) (tmp) / n;
printf("%.3lf",sqrt(r-t));
}

[NOI1999] 棋盘分割的更多相关文章

  1. [NOI1999] 棋盘分割(推式子+dp)

    http://poj.org/problem?id=1191 棋盘分割 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 156 ...

  2. POJ1991 NOI1999棋盘分割

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

  3. POJ 1191 棋盘分割

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

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

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

  5. NOI 193棋盘分割.cpp

    193:棋盘分割 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的部分 ...

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

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

  7. POJ 1191棋盘分割问题

    棋盘分割问题 题目大意,将一个棋盘分割成k-1个矩形,每个矩形都对应一个权值,让所有的权值最小求分法 很像区间DP,但是也不能说就是 我们只要想好了一个怎么变成两个,剩下的就好了,但是怎么变,就是变化 ...

  8. 洛谷 P1436 棋盘分割 解题报告

    P1436 棋盘分割 题目描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的两部分中的任意一块继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共 ...

  9. poj1191 棋盘分割【区间DP】【记忆化搜索】

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

随机推荐

  1. Leetcode题库——28.实现strStr()

    @author: ZZQ @software: PyCharm @file: strStr.py @time: 2018/11/6 20:04 要求:给定一个 haystack 字符串和一个 need ...

  2. Sprint计划(未完成)

    1.需求预计:http://www.cnblogs.com/OuZeBo/p/4529320.html 2.功能设计: 3.Spring计划:

  3. 超实用 1 ArrayList 链表

    package ArrayList链表; import java.util.*; public class kk1 { /** * 作者:Mr.Fan * 功能:记住ArrayList链表 */ pu ...

  4. wcf服务查看工具

    文章:接口测试工具soapUI(一) 文章:VS自带WCF测试客户端简单介绍

  5. 【转】Verilog HDL常用建模方式——《Verilog与数字ASIC设计基础》读书笔记(四)

    Verilog HDL常用建模方式——<Verilog与数字ASIC设计基础>读书笔记(四) Verilog HDL的基本功能之一是描述可综合的硬件逻辑电路.所谓综合(Synthesis) ...

  6. jQuery扩展插件

    jQuery有多好用,大家有目共睹的,但是有时候不是每个功能都是万能的,有时候我们需要实现自己的功能,jQuery提供了很好的拓展功能,我们可以去拓展插件,更好的利用jQuery 查看官网,可知,有两 ...

  7. 使用 oracle pipelined 返回一个结果集;

    1.使用 create or replace package refcursor_pkg is -- Author : mr.yang -- Created : 5/14/2017 5:13:42 P ...

  8. XHTML和HTML、CSS 验证器

    XHTML 验证器和 CSS 验证器.需要这些工具去验证你的页面是否符合 XHTML 和 CSS 标准,并且可以使用它查出奇正错误的地方. XHTML 验证器 地址:http://validator. ...

  9. [转帖]学习一下centos7 新地方

    总结的挺好  copy一下 慢慢学习: http://blog.itpub.net/312079/viewspace-2214440/ Centos7 单用户模式 centos7里不再有0-6启动级别 ...

  10. testdisk修复文件系统

    故障修复步骤: 1. 检查磁盘分区级文件系统确实不在: 2. 云主机内部下载testdisk工具修复 yum install testdisk -y 3. 执行命令testdisk /dev/vdc进 ...