背包dp

一道很早以前就见过的dp

dp[i][j][k]表示选到第i本书,第一层宽度为j,第二层宽度为k的最小高度,我们先把书按高度排序,然后转移就很方便了,因为高度降序,所以后选的书不影响之前选的,也就是说只有当前层没放过书才用这本书更新,否则维护原来的值,然后滚动数组,卡卡常数就过了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = ;
struct data {
int h, t;
bool friend operator < (const data &a, const data &b) {
return a.h > b.h;
}
} a[N];
int pre, n;
ll ans = 1000000000000000ll;
int dp[][N][N], sum[N];
int main()
{
scanf("%d", &n);
for(int i = ; i <= n; ++i) scanf("%d%d", &a[i].h, &a[i].t);
sort(a + , a + n + );
for(int i = ; i <= n; ++i) sum[i] = sum[i - ] + a[i].t;
memset(dp, 0x3f3f, sizeof(dp));
dp[pre][][] = ;
for(int i = ; i <= n; ++i)
{
pre ^= ;
memset(dp[pre], 0x3f3f, sizeof(dp[pre]));
for(int j = ; j <= sum[n]; ++j)
for(int k = ; k <= sum[n]; ++k) if(dp[pre ^ ][j][k] < 0x3f3f3f3f)
{
if(j == ) dp[pre][j + a[i].t][k] = min(dp[pre][j + a[i].t][k], dp[pre ^ ][j][k] + a[i].h);
else if(j + a[i].t <= sum[n]) dp[pre][j + a[i].t][k] = min(dp[pre][j + a[i].t][k], dp[pre ^ ][j][k]);
if(k == ) dp[pre][j][k + a[i].t] = min(dp[pre][j][k + a[i].t], dp[pre ^ ][j][k] + a[i].h);
else if(k + a[i].t <= sum[n]) dp[pre][j][k + a[i].t] = min(dp[pre][j][k + a[i].t], dp[pre ^ ][j][k]);
if(sum[i] - j - k == a[i].t) dp[pre][j][k] = min(dp[pre][j][k], dp[pre ^ ][j][k] + a[i].h);
else if(sum[i] - j - k > a[i].t) dp[pre][j][k] = min(dp[pre][j][k], dp[pre ^ ][j][k]);
}
}
for(int i = ; i <= sum[n]; ++i)
for(int j = ; j <= sum[n]; ++j) if(i + j < sum[n] && dp[pre][i][j] < 0x3f3f3f3f) ans = min(ans, (max((ll)i, max((ll)j, sum[n] - (ll)i - (ll)j)) * (ll)dp[pre][i][j]));
printf("%lld\n", ans);
return ;
}

bzoj1933的更多相关文章

  1. BZOJ1933: [Shoi2007]Bookcase 书柜的尺寸

    传送门 很容易看出来这是一道DP题,那么怎么设置状态就成了这道题的关键.本题有点特殊的地方是有两个维度的状态,而每个维度又有三个部分的参数,如果全部设置出来的话肯定会MLE.首先对书的厚度状态简化. ...

随机推荐

  1. iOS时钟,秒针扫秒样式

    昨天做一个时钟小demo,发现了一些问题. 描述能力有限,我封装好了一个时钟框架,朋友们可以参考      https://github.com/qianlishun/ClockView 点击这里可以 ...

  2. CPU问题定位与解决

    CPU问题定位基本流程:   性能计数器诊断 主要用到的性能计数器 %Process Time 全实例 (主要用于查看当前服务器的CPU 情况) %Process Time sqlservr (主要用 ...

  3. transient 关键字

    java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持.换句话来说就是,用transient关键字标记的成员变量不参与序列化过程.   作用 Jav ...

  4. Codeforces 653B Bear and Compressing【DFS】

    题目链接: http://codeforces.com/problemset/problem/653/B 题意: 要求你构造一个长度为n的字符串使得通过使用m个操作,最终获得字符a.已知第i个操作将字 ...

  5. union关键字和字节大小端序的确定

    union 关键字的用法与struct 的用法非常类似. union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间 ...

  6. [Noip复习知识点][个人向]Zackzh

    只是列列一些要复习的,努力复习吧,有种noip退役的赶脚. 一.模拟 (这你也不会?退役吧) 二.DP 1.基础dp 2.区间dp 3.状压dp 4.树形dp 6.概率(期望)dp 7.环形dp 8. ...

  7. 2017多校Round3(hdu6056~hdu6066)

    补题进度:7/11 1001 待填坑 1002 待填坑 1003(set) 题意: 给定长度为n(n<=5e5)的数组(是n的一个排列)和一个整数k(k<=80),f[l,r]定义为区间[ ...

  8. 09-js数组常用方法

    <html> <head> <title>js数组的常用操作</title> <meta charset="UTF-8"/&g ...

  9. Java的变量类型

    以下内容引用自http://wiki.jikexueyuan.com/project/java/variable-types.html: 一个变量提供了程序可以操作的命名存储.Java中的每个变量都有 ...

  10. GreenDao数据库的升级

    应用使用了GreenDao数据库,在版本升级的时候需要更改dao的字段,新增.修改.删除字段操作,如果直接删除原来的表的话那用户原来的一些数据就没有了,所以在更新数据库的时候需要做一次封装,把原来的数 ...