[SHOI2007] 书柜的尺寸 思维题+Dp+空间优化
Online Judge:Luogu-P2160
Label:思维题,Dp,空间优化
题面:
题目描述
给\(N\)本书,每本书有高度\(Hi\),厚度\(Ti\)。要摆在一个三层的书架上。
书架的宽是每层书厚度和的最大值。书架的高度是每层最高书的高度之和。
求如何放书,使得书架的面积最小。
输入
第一行一个整数\(n\),表示书本的个数。
接下来\(n\)行,每行2个整数,表示每本书的高度和厚度。
输出
输出一个整数,表示书架的最小面积。
样例
Input
4
220 29
195 20
200 9
180 30
6
256 20
255 30
254 15
253 20
252 15
251 95 2
25 25 32 32 25
5 1
25 26 25 26 25
0 0
Output
18000
29796
提示
每层书架都必须有书。
样例1:第一本书在第一层,第二本、第三本书在第二层,第四本书在第三层!
高度是220+200+180=600,宽度为max(29,29,30)=30,总面积18000。
对于100%的数据,n的范围\([3,70]\),h[i]的范围\([150,300]\),t[i]的范围\([1,30]\)。
题解
首先注意到一点,高度最高的那本书,不论我们把它放在1、2、3层,它都会成为它那一层的最高。所以不妨先确定下这本书,把这本高度最高的书放在第一层,那么第一层在高度上对答案的贡献就可以确定为这个最大高度了。
如何去安排上面两层使得面积最小呢。现在存在两维——高度和宽度,我们尝试利用Dp消掉其中一个来简化问题。
1.定义
定义状态\(dp[i][p1][p2]\)表示,已经摆放好了前\(i\)本书(注意到摆书的顺序对答案是没有影响的),第二层剩余的宽度为\(p1\),第三层剩余的宽度为\(p2\),此时二三两层加起来的总高度最小能为多少。
2.转移
等等,这样该如何转移呢?按常规转移思路来说应该还得记录下其中一层的高度,不然我现在放的书比之前放在这一层的那本书高度要大时,理应更新这一层在高度上对答案的贡献才对,但我此刻却不知道之前这一层的高度是多少。
解决方案不难想到,我们可以直接从大到小排序高度,那么假如这本书是当前层所放的第一本书,那么这一层在高度上对答案的贡献就确定了(后面不会再有书比现在的书高了)。
这样我们就可以利用填表进行转移勒:
初态:\(dp[i][p1][p2]=\)INF,$dp[1][0][0]=$1。
inline void Do(int &x,int y){if(x>y)x=y;}
枚举i,j,k{
if(a[i].w<j)Do(dp[j][k],dp[j-a[i].w][k]);
else if(j==a[i].w)Do(dp[j][k],dp[0][k]+a[i].h);//i是第二层放的第一本书
if(a[i].w<k)Do(dp[j][k],dp[j][k-a[i].w]);
else if(k==a[i].w)Do(dp[j][k],dp[j][0]+a[i].h);//i是第三层放的第一本书
}
终态:枚举\(p1,p2\),\(ans=max(ans,H*W)\),其中\(H=dp[n][p1][p2]+Maxheight\),\(W=max(p1,max(p2,Lim-p1-p2)\),\(Lim\)表示所有书的宽度之和。
3.空间优化
还有一个问题就是空间显然会炸。
第一种解决方案:根据上面的转移顺序可以知道,对于第\(i\)本书,只会用到第\(i-1\)本书的状态,所以显然可以把第一维给滚动了。
第二种解决方案:但也可以直接去掉这一维而无需滚动。但是转移顺序得稍微调整一下,我们上面枚举的\(j,k\)得从大到小枚举,这和01背包倒着循环是一个道理。
4.一点时间上的小优化
前面枚举\(j,k\)的上限不必为\(Lim\)(所有书本的宽度总和),可以用前缀和来代替,从而省去很多无用的枚举。
综上此做法时间复杂度为\(O(N*Lim*Lim)\),其中\(N<=70,Lim<=2100\)。
完整代码如下:
#include<bits/stdc++.h>
using namespace std;
const int INF=1890000;
inline int read(){}
int n,m,Lim;
int dp[2200][2200],sum[75];
struct node{int h,w;}a[75];
inline bool cmp(node x,node y){return x.h>y.h;}
inline void Do(int &x,int y){if(x>y)x=y;}
int main(){
n=read();
for(register int i=1;i<=n;i++){
a[i].h=read(),a[i].w=read();
Lim+=a[i].w;
}
sort(a+1,a+n+1,cmp);
for(register int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i].w;
for(register int i=0;i<=Lim;i++)for(register int j=0;j<=Lim;j++)dp[i][j]=INF;
dp[0][0]=0;
for(register int i=2;i<=n;i++){
for(register int j=sum[i];j>=0;j--)for(register int k=sum[i];k>=0;k--){
if(a[i].w<j)Do(dp[j][k],dp[j-a[i].w][k]);
else if(j==a[i].w)Do(dp[j][k],dp[0][k]+a[i].h);
if(a[i].w<k)Do(dp[j][k],dp[j][k-a[i].w]);
else if(k==a[i].w)Do(dp[j][k],dp[j][0]+a[i].h);
}
}
int ans=INF;
for(register int i=1;i<=Lim;i++)for(register int j=1;j<=Lim;j++){
if(dp[i][j]==INF)continue;
int H=dp[i][j]+a[1].h,W=max(Lim-i-j,max(i,j));
Do(ans,H*W);
}
printf("%d\n",ans);
}
END
当题目中存在多种决定因素时,可以考虑使用Dp求最值来消去其中的一维或多维。
通过排序等方法来改变转移顺序,从而简化问题。
[SHOI2007] 书柜的尺寸 思维题+Dp+空间优化的更多相关文章
- 树形dp空间优化(dfn)
树形dp空间优化 介绍 有时题目会告诉我们n叉树的最大层数,或者给出一个完全n叉树树,直接做树形dp会爆空间时,就可以用这个优化方法. 多数树形dp都是先dfs到子树,再合并到根上,显然当合并到根上时 ...
- Codeforces 1038D - Slime - [思维题][DP]
题目链接:http://codeforces.com/problemset/problem/1038/D 题意: 给出 $n$ 个史莱姆,每个史莱姆有一个价值 $a[i]$,一个史莱姆可以吃掉相邻的史 ...
- lightoj 1145 - Dice (I)(dp+空间优化+前缀和)
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1145 题解:首先只要是dp的值只和上一个状态有关系那么就可以优化一维,然后这题 ...
- bzoj3687简单题(dp+bitset优化)
3687: 简单题 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 861 Solved: 399[Submit][Status][Discuss] ...
- [UVA12235] Help Bubu 思维题+状态定义+Dp
Online Judge:UVA12235 Label:思维题,状态定义,状压Dp 题面: 题目描述 有一个书架,上面放了n本书,从左往右的第i本书的高度为h[i].定义书架的混乱度为连续等高段的个数 ...
- BZOJ 2734 洛谷 3226 [HNOI2012]集合选数【状压DP】【思维题】
[题解] 思维题,看了别人的博客才会写. 写出这样的矩阵: 1,3,9,... 2,6,18,... 4,12.36,... 8,24,72,... 我们要做的就是从矩阵中选出一些数字,但是不能选相邻 ...
- [NOIP2005] 过河【Dp,思维题,缩点】
Online Judge:Luogu P1052 Label:Dp,思维题,缩点,数学 题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子 ...
- [Hdu-5155] Harry And Magic Box[思维题+容斥,计数Dp]
Online Judge:Hdu5155 Label:思维题+容斥,计数Dp 题面: 题目描述 给定一个大小为\(N*M\)的神奇盒子,里面每行每列都至少有一个钻石,问可行的排列方案数.由于答案较大, ...
- 7月15日考试 题解(链表+状压DP+思维题)
前言:蒟蒻太弱了,全打的暴力QAQ. --------------------- T1 小Z的求和 题目大意:求$\sum\limits_{i=1}^n \sum\limits_{j=i}^n kth ...
随机推荐
- HTML加载顺序
一.js执行顺序 //1. 外部引入的js文件,会异步下载并且执行(<script>块中的语句),根据引入的位置会在不同时刻执行 //2.$().ready(function() {}) ...
- Linux命令速查手册(第2版)学习
第1章.需要了解的命令行相关事项 表1-1 如何在文件名字符中使用特殊字符 字符 建议 / 绝不使用.不能转义 \ 必须转义.避免使用 _ 绝不能作为文件或目录名的第一个字符 [] 必须转义.避免使用 ...
- Javascript加载talbe(包含分页、数据下载功能)
效果图如下: 首先简单说明一下,后面会给所涉及到的代码都贴上来的. 1.excel图标是一个用户控件,用来触发下载 2.首页.上页......每页多少条,这一块是一个整体,你可以选择放置在表格下面,或 ...
- thinkphp import标签
传统方式的导入外部JS和CSS文件的方法是直接在模板文件使用: 直线电机哪家好 <script type='text/javascript' src='/Public/Js/Util/Array ...
- (转)[视频压制/转换技术] I帧 B帧 P帧 IDR帧 等帧用途详细说明
转:http://www.u2game.net/bbs/thread-46116-1-1.html 在视频压制.转换中,经常会看到:I帧 B帧 P帧 IDR帧 等名词,这里就是通用的解释一下这些帧的用 ...
- Spring基础面试题(一)
Spring是什么? Spring是一个轻量级的IoC和AOP容器框架.是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求.常见的配置方式有 ...
- iis网站域名绑定
这里解释两种绑定 一.全局ip未分配 二.绑定指定域名 1.添加主机名 注释:没有绑定主机名的进站默认就会被访问.绑定主机名的进站访问特定主机名的网站.
- div中包着文字,div出现隐藏的时候,文字总是在div外面。
背景: 给博客加一个侧边栏,点击出现隐藏,每次点击出现或者隐藏,文字总是很突兀的就出来了. 解决: overflow:hidden
- SQL的语言分类
SQL的语言分类 DQL DQL(Data Query Language):数据查询语言 select DML DML(Data Manipulate Language):数据操作语言 insert ...
- R:ggplot2数据可视化——进阶(2)
Part 2: Customizing the Look and Feel, 更高级的自定义化,比如说操作图例.注记.多图布局等 # Setup options(scipen=999) librar ...