题目描述

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

原棋盘上每一格有一个分值,一块矩形棋盘的总分为其所含各格分值之和。现在需要把棋盘按上述规则分割成n块矩形棋盘,并使各矩形棋盘总分的平方和最小。

请编程对给出的棋盘及n,求出平方和的最小值。

解析

\(dp[k][i][j][x][y]\)表示当前在切第k刀,当前切\((i,j)\)为左上角,\((x,y)\)为右下角的矩形的最小平方和。

考虑状态转移,一个状态转移到下一个时,它可以继续往两个部分切下去,也就是往两个方向转移。

采用前缀和优化,其中\(calc(i,j,x,y)\)表示以\((i,j)\)为左上角,\((x,y)\)为右下角的矩形的和的平方。

\[dp[k][i][j][x][y]=min(dp[k][i][j][x][y],dp[k-1][i'+1][j][x][y]+calc(i,j,i',y),
\\dp[k-1][i][j][x'][y]+calc(x'+1,j,x,y))
\]

\[dp[k][i][j][x][y]=min(dp[k][i][j][x][y],dp[k-1][i][j'+1][x][y]+clac(i,j,x,j'),
\\dp[k-1][i][j][x][y']+calc(i,y',x,y))
\]

初始化显然是切第0刀时,切任意矩形的最小平方和就是不切,就是该矩形的和的平方。

之前的思路和这个稍稍有些不同,我定义dp数组为当前切剩下以\((i,j)\)为左上角,\((x,y)\)为右下角的矩形的最小平方和,那么就需要四个转移,但是我转移写炸了(摊。

参考代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 11
#define MOD 2520
#define E 1e-12
using namespace std;
int dp[16][N][N][N][N],mp[N][N],n;
inline int read()
{
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
inline int calc(int x1,int y1,int x2,int y2)
{
if(x1>x2) swap(x1,x2);
if(y1>y2) swap(y1,y2);
return (mp[x2][y2]-mp[x1-1][y2]-mp[x2][y1-1]+mp[x1-1][y1-1])*(mp[x2][y2]-mp[x1-1][y2]-mp[x2][y1-1]+mp[x1-1][y1-1]);
}
int main()
{
n=read();
memset(dp,0x3f,sizeof(dp));
memset(dp[0],0,sizeof(dp[0]));
for(int i=1;i<=8;++i)
for(int j=1;j<=8;++j){
dp[0][i][j][i][j]=mp[i][j]=read();
mp[i][j]+=mp[i-1][j]+mp[i][j-1]-mp[i-1][j-1];
}
for(int i=1;i<=8;++i)
for(int j=1;j<=8;++j)
for(int x=i;x<=8;++x)
for(int y=j;y<=8;++y)
dp[0][i][j][x][y]=calc(i,j,x,y);
for(int k=1;k<n;++k){
for(int i=1;i<=8;++i)
for(int j=1;j<=8;++j)
for(int x=i;x<=8;++x)
for(int y=j;y<=8;++y){
for(int dx=i;dx<=x;++dx)
dp[k][i][j][x][y]=min(dp[k][i][j][x][y],min(dp[k-1][i][j][dx][y]+calc(dx+1,j,x,y),dp[k-1][dx+1][j][x][y]+calc(i,j,dx,y)));
for(int dy=j;dy<=y;++dy)
dp[k][i][j][x][y]=min(dp[k][i][j][x][y],min(dp[k-1][i][j][x][dy]+calc(i,dy+1,x,y),dp[k-1][i][dy+1][x][y]+calc(i,j,x,dy)));
}
}
cout<<dp[n-1][1][1][8][8]<<endl;
return 0;
}

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

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

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

  2. Luogu P1436 棋盘分割 暴力DP

    我的天,,,,,n=8,k<=15,,,这怕不是暴力DP+高维数组.... 开一个五维数组f[k][i][j][p][q]表示从(i,j)到(p,q)中分成k个矩形最小的平方和. 然后初始化时用 ...

  3. 【Luogu】P1436 棋盘分割 题解

    嗯,点开题目,哇!是一道闪亮亮的蓝题! 不要被吓到了,其实,这道题就是一个简单的DP啦! 我们设 \(f[x1][y1][x2][y2][c]\) 为以 \((x1,y1)\) 为左上角,以 \((x ...

  4. POJ 1191 棋盘分割(DP)

    题目链接 大体思路看,黑书...其他就是注意搞一个in数组,这样记忆化搜索,貌似比较快. #include <cstdio> #include <cstring> #inclu ...

  5. NOI1999 JZYZOJ1289 棋盘分割 dp 方差的数学结论

    http://172.20.6.3/Problem_Show.asp?id=1289 除了下标一坨一坨屎一样挺恶心其他都还挺容易的dp,这道题才发现scanf保留小数位是四舍五入的,惊了. f[k][ ...

  6. 洛谷P1436 棋盘分割

    洛谷题目链接 动态规划: 我们设状态$f[i][j][o][p][k]$表示一个矩形,左上角顶点坐标为$(i,j)$,右下角顶点坐标为$(o,p)$时分割了$k$次,也就是说现在是$k+1$块 我们考 ...

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

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

  8. [POJ] 1191 [LUOGU] P1436 棋盘分割

    那个均方差,可以通过展开.合并Σ,发现最终只有Xi^2会对答案造成影响,其他都是定值,所以求出最小的和的平方就行. 其实这才是这题最难的部分,以下都是码农部分. f[x1][y1][x2][y2][k ...

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

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

随机推荐

  1. 码云初次导入项目(Idea)

    一.新建项目  使用ssh时记得配置码云的个人中的秘钥 [问题原因] 远程仓库和本地仓库的内容不一致 [解决方法] 在git项目对应的目录位置打开Git Bash   然后在命令窗输入下面命令: gi ...

  2. 【编程开发】x86,I386,i686, x86_64, x64,amd64、Windows Linux AIX下查看CPU位数和操作系统位数、rpm包名

    a2ps-4.13b-57.2.el5.i386.rpm 每一个rpm包的名称都由"-"和"."分成了若干部分.就拿 a2ps-4.13b-57.2.el5.i ...

  3. springboot实战日记(一)数据库基本信息

    摘要:基于spring boot的后端实现,开发一个微信小程序点餐系统,主要是写写思路和遇到的问题以及分享读到的好文章. 项目分析: 1.角色划分,就是开有什么人使用这个系统,买家(手机端),卖家(p ...

  4. Coursera,Udacity,Edx 课程列表(更新ing)

    Coursera,Udacity,Edx 课程列表(更新ing) Coursera有很多特别好的课程,平时没有机会听到国外大牛的课程,通过Coursera算是可以弥补一下吧,国外的课程普遍比国内的老师 ...

  5. docker使用2

    新建并启动容器 docker  run  [options]  imageId options -i  以交互模式运行容器 -t  为容器重新分配一个为终端设备 -p  主机端口:容器端口 --nam ...

  6. C++的派生类构造函数是否要带上基类构造函数

    //public:Student(int s_age):People(s_age) //C++的派生类构造函数后面是否带上基类构造函数,取决于基类构造函数是否需要传入参数,如果要参数,就一定带上:不需 ...

  7. 使用 python 进行微信好友分析

    使用 python 进行微信好友分析 1. 使用到的库 ① wxpy:初始化微信机器人 ② openpyxl:保存微信好友数据为Excel表格 ③ pyecharts:生成可视化的地图 ④ wordc ...

  8. DolphinPHP(海豚框架)初步学习

    由于工作原因需要学习DolphinPHP框架,在此记录一下! 首先交代下环境,我用的是phpStudy集成环境,然后海豚框架是最新的1.4.2版本 ok,接下来我们开始学习,最基础的,是我们需要将我们 ...

  9. 计算GPA

    #include <stdio.h> int main() { int n,t,i; float sum,s,p,m,k; while(~scanf("%d",& ...

  10. wpf 对控件进行截图,获取快照

    有时候我们项目,在执行某个操作后,会生成一些数据结果,如报表一类的东西,我们需要对结果进行保存,甚至是生成word文档. 那么首先获取到控件快照就最基本的条件. 生成快照的静态方法类 using Sy ...