bzoj1933
背包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的更多相关文章
- BZOJ1933: [Shoi2007]Bookcase 书柜的尺寸
传送门 很容易看出来这是一道DP题,那么怎么设置状态就成了这道题的关键.本题有点特殊的地方是有两个维度的状态,而每个维度又有三个部分的参数,如果全部设置出来的话肯定会MLE.首先对书的厚度状态简化. ...
随机推荐
- POJ2455 Secret Milking Machine【二分,最大流】
题目大意:N个点P条边,令存在T条从1到N的路径,求路径上的边权的最大值最小为多少 思路:做了好多二分+最大流的题了,思路很好出 二分出最大边权后建图,跑dinic 问题是....这题是卡常数的好题! ...
- ACDream:1210:Chinese Girls' Amusement【水题】
Chinese Girls' Amusement Time Limit: 2000/1000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Oth ...
- 【贪心+二分】codeforces C. Sagheer and Nubian Market
http://codeforces.com/contest/812/problem/C [题意] 如何花最少的钱买最多的纪念品?首要满足纪念品尽可能多,纪念品数量一样花钱要最少,输出纪念品数量以及最少 ...
- Linux(5):正则表达式 & 权限
正则表达式: 特殊符号: '' ---> 所见即所得,里面的内容都会被原封不动的输出出来 "" ---> 与单引号类似,但其中的特殊符号会被解析运行 `` ---> ...
- 数据库备份与还原c#.net实现
原文发布时间为:2008-10-25 -- 来源于本人的百度文章 [由搬家工具导入] 数据库备份与还原c#.net实现: 页面上面有 备份,还原,下拉菜单(浏览备份文件夹下面的所有文件名),删除(删除 ...
- 【git】git回退到某个历史版本(强行推送代码)
1. 使用git log命令查看所有的历史版本,获取某个历史版本的id,假设查到历史版本的id是139dcfaa558e3276b30b6b2e5cbbb9c00bbdca96. 2. 3. 把修改推 ...
- poj1523求割点以及割后连通分量数tarjan算法应用
无向图,双向通道即可,tarjan算法简单应用.点u是割点,条件1:u是dfs树根,则u至少有2个孩子结点.||条件2:u不是根,dfn[u]=<low[v],v是u的孩子结点,而且每个这样的v ...
- python学习之 -- 数据序列化
json / pickle 数据序列化 序列化定义:把变量从内存中变成可存储或传输的过程称为序列化.反序列化:把变量内容从序列化的对象重新读到内存里称为反序列胡. 序列化模块之--pickle使用注意 ...
- 元数据的概念以及相关的操作os模块、shutil模块
查看文件的元数据 stat [OPTION]… FILE… OPTION: -f 输出文件系统的状态,而非文件的状态 -t 显示简要格式的文件元数据信息 FILE:可同时查看多个文件的元数据信息,多个 ...
- 编程基础知识——Java JNI开发流程(2)
android中使用jni调用本地C++库 android平台上的本地库文件后缀 .so.类似windows上的dll文件. 要在android上使用jni.首先须要下载android ndk. 操作 ...