题意:有 n 本书,每本书有一个高度和宽度,然后让你制作一个3层的书架,可以放下所有的书,并且要高*宽尽量小。

析:先把所有的书按高度进行排序,然后dp[i][j][k] 表示 前 i 本书,第二 层的宽度是 j,第三层的宽度是 k,第二层和第三层的高度最小,首先我们可以先最高的那本书放到第一层,那么这一层的高度就确定了,同理,在放第二层和第三层的时候,如果是第一本书,那么这一层的高度就已经确定了,为什么不表示第一层的宽度呢,因为总宽度是确定的,如果第二层的宽度和第三层的宽度知道了,那么第一层也就确定了。有了这些就可以进行状态转移了。注意不要转移无用的状态以降低时间复杂度。

有三种决策,1 放在第一层,dp[i+1][j][k] = min{ dp[i][j][k] }

2.放在第二层,那么又有两种情况,第一次放,还是不是第一次放

if(j == 0)  dp[i+1][j+w][k] = min{ dp[i][j][k] + h }

else  dp[i+1][j+w][k] = min{ dp[i][j][k] }

3.放在第三层,这一种和第二层一样。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define pu push_up
#define pd push_down
#define cl clear()
#define all 1,n,1
#define FOR(x,n) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 200000 + 10;
const LL mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r > 0 && r <= n && c > 0 && c <= m;
} int dp[2][2105][2105];
struct Node{
int h, w;
bool operator < (const Node &p) const {
return h > p.h;
}
};
Node a[80];
int sum[maxn]; int main(){
int T; cin >> T;
while(T--){
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%d %d", &a[i].h, &a[i].w);
sort(a + 1, a + n + 1);
for(int i = 2; i <= n; ++i) sum[i] = sum[i-1] + a[i].w;
int cnt = 0;
ms(dp[0], INF);
dp[0][0][0] = 0;
for(int i = 1; i < n; ++i, cnt ^= 1){
ms(dp[cnt^1], INF);
for(int j = 0; j <= sum[i]; ++j){
for(int k = 0; k <= sum[i]; ++k){
if(j + k > sum[i]) break;
if(dp[cnt][j][k] == INF) continue;
dp[cnt^1][j][k] = min(dp[cnt^1][j][k], dp[cnt][j][k]);
if(j == 0) dp[cnt^1][a[i+1].w][k] = min(dp[cnt^1][a[i+1].w][k], dp[cnt][j][k] + a[i+1].h);
else dp[cnt^1][j+a[i+1].w][k] = min(dp[cnt^1][j+a[i+1].w][k], dp[cnt][j][k]);
if(k == 0) dp[cnt^1][j][a[i+1].w] = min(dp[cnt^1][j][a[i+1].w], dp[cnt][j][k] + a[i+1].h);
else dp[cnt^1][j][k+a[i+1].w] = min(dp[cnt^1][j][k+a[i+1].w], dp[cnt][j][k]);
}
}
} int ans = INF;
for(int i = 0; i <= sum[n]; ++i)
for(int j = 0; j <= sum[n]; ++j){
if(i + j > sum[n]) break;
if(dp[cnt][i][j] == INF) continue;
if(i == 0 || j == 0) continue;
ans = min(ans, (dp[cnt][i][j] + a[1].h) * max(j, max(i, sum[n]-j-i+a[1].w)));
}
printf("%d\n", ans);
}
return 0;
}

  

UVa 12099 The Bookcase (DP)的更多相关文章

  1. UVa 12099 The Bookcase - 动态规划

    题目大意 给定一些书,每个书有一个高度和宽度,然后将它们放到一个三层的书架里(要求每一层都不为空).定义书架的大小为每层最大的高度和 乘 每层宽度和的最大值.求最小的书架大小. 显然动态规划(直觉,没 ...

  2. UVA - 12099 The Bookcase

    No wonder the old bookcase caved under the massive piles of books Tom had stacked on it. He had bett ...

  3. 【暑假】[深入动态规划]UVa 10618 The Bookcase

    UVa 12099  The Bookcase 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=42067 思路:    ...

  4. UVA.674 Coin Change (DP 完全背包)

    UVA.674 Coin Change (DP) 题意分析 有5种硬币, 面值分别为1.5.10.25.50,现在给出金额,问可以用多少种方式组成该面值. 每种硬币的数量是无限的.典型完全背包. 状态 ...

  5. uva 10817(数位dp)

    uva 10817(数位dp) 某校有m个教师和n个求职者,需讲授s个课程(1<=s<=8, 1<=m<=20, 1<=n<=100).已知每人的工资c(10000 ...

  6. UVA 11404 Palindromic Subsequence[DP LCS 打印]

    UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求L ...

  7. uva 10453 - Make Palindrome(dp)

    题目链接:10453 - Make Palindrome 题目大意:给出一个字符串,通过插入字符使得原字符串变成一个回文串,要求插入的字符个数最小,并且输出最后生成的回文串. 解题思路:和uva 10 ...

  8. uva 10671 - Grid Speed(dp)

    题目链接:uva 10671 - Grid Speed 题目大意:给出N,表示在一个N*N的网格中,每段路长L,如今给出h,v的限制速度,以及起始位置sx,sy,终止位置ex,ey,时间范围st,et ...

  9. uva 1331 - Minimax Triangulation(dp)

    option=com_onlinejudge&Itemid=8&page=show_problem&category=514&problem=4077&mosm ...

随机推荐

  1. PyQt 5布局管理

    绝对定位 绝对定位有以下限制 1.如果调整窗口,控件的大小和位置不会改变 2.在各种平台上应用程序看起来不会一样 3.如果改变字体,我们的应用程序的布局就会改变 4.如果我们决定改变我们的布局,我们必 ...

  2. DBA_2PC_PENDING (转)

    DBA_2PC_PENDINGOracle会自动处理分布事务,保证分布事务的一致性,所有站点全部提交或全部回滚.一般情况下,处理过程在很短的时间内完成,根本无法察觉到.但是,如果在commit或rol ...

  3. FreeRADIUS 、DaloRADIUS 搭建记录

    一.  安装环境 系统环境:centos6.5 IP:192.168.30.242 hostname:vpn.org 软件:PPTP.LAMP均已安装.(请确保这些正常安装,并能使用). 二.  软件 ...

  4. Linux的bond模式绑定及模式区别

    [Linux的bond模式配置] 原理: 多块网卡虚拟成一张,实现冗余:多张网卡对外显示一张,具有同一个IP: 工作在网卡是混杂模式的情况下: 对于多物理网卡的 Bond 网卡而言,其中一块物理网卡会 ...

  5. Cisco动态路由 OSPF协议

    OSPF描述: 组播扩展OSPF  锁定 同义词 ospf一般指组播扩展OSPF 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . OSPF(Open Shortest Path Firs ...

  6. Android APP压力测试实战

    环境准备: Android SDK Python   压测实战步骤 1.在手机开发者工具中,将USB调试选上 2.确认手机,电脑成功连接(通过adb devices) 3.安装测试app(adb in ...

  7. **类的起源--type

    通过type类的实例化,创建新的类. #!/usr/bin/env python # Version = 3.5.2 def func(self): print('Hello,{}'.format(s ...

  8. Ubuntu 查看磁盘空间大小命令<转>

    df -h Df命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息,命令格式: df -hl 显示格式为: 文件系统 容量 已用 可用 已用% 挂载点 Filesyst ...

  9. fastjson集合转字符串

    JSON.toJSONString(list, SerializerFeature.DisableCircularReferenceDetect); list为集合

  10. Java如何快速修改Jar包里的文件内容

    需求背景:写了一个实时读取日志文件以及监控的小程序,打包成了Jar包可执行文件,通过我们的web主系统上传到各个服务器,然后调用ssh命令执行.每次上传前都要通过解压缩软件修改或者替换里面的配置文件, ...