HDU 2844:Coins(多重背包)
来源:互联网 发布:js实现select 编辑:程序博客网 时间:2024/05/17 04:45
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2844
有 N 种物品和一个容量为 V 的背包。第 i 种物品最多有 ci 件可用,每件耗费的 空间是 wi,价值是 vi。求解将哪些物品装入背包可使这些物品的耗费的空间总和不超 过背包容量,且价值总和最大。这样的是多重背包。
多重背包有的暴力就是在01背包的基础上多一重循环:for(k=1;k<=c[i];k++);
使 dp[j]=max(dp[j],dp[j-k*w[i]]+k*v[i]);
但是这样做大多会超时,所以就有了二进制的思想。
我们把第 i 个物品分割成多个01背包。也就是分成:2^0,2^1,2^2,2^(k-1),c[i]+1-2^k.
比如有一种物品有13件,就分成:1,2,4,6 的4件物品。
#include"stdlib.h"#include"stdio.h"#include"string.h"#include"iostream"using namespace std;int dp[100005]; //数组太小会越界int main(){ int n,m; while(scanf("%d %d",&n,&m)!=EOF) { if(n==0&&m==0)break; int a[105],c[105],t=0; for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&c[i]); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { if(c[i]*a[i]>m) //此条件成立可以看作是完全背包 for(int j=a[i];j<=m;j++) dp[j]=max(dp[j],dp[j-a[i]]+a[i]); else { int k=1,s=c[i]; while(s>k) //二进制思想 { for(int j=m;j>=a[i]*k;j--) { dp[j]=max(dp[j],dp[j-a[i]*k]+a[i]*k); } s=s-k; k=k*2; } for(int j=m;j>=a[i]*s;j--) dp[j]=max(dp[j],dp[j-a[i]*s]+a[i]*s); } } /*for(int i=1;i<=m;i++) printf("%d ",dp[i]); printf("\n");*/ //测试 for(int i=1;i<=m;i++) if(dp[i]==i) t++; printf("%d",t); printf("\n"); } return 0;}
0 0
- hdu 2844 Coins 多重背包
- hdu 2844 Coins 多重背包
- HDU 2844 Coins -- 多重背包
- hdu 2844 Coins - 多重背包
- hdu 2844 Coins(多重背包)
- hdu 2844 Coins 多重背包
- Coins hdu 多重背包 2844
- HDU 2844 Coins 多重背包
- HDU-2844-Coins(多重背包)
- HDU 2844 Coins(多重背包)
- HDU 2844:Coins(多重背包)
- HDU 2844(Coins)多重背包
- hdu 2844 Coins (多重背包)
- HDU - 2844 Coins(多重背包)
- HDU 2844 Coins 多重背包
- hdu 2844 coins 多重背包
- hdu 2844 Coins【多重背包】
- HDU 2844-Coins(多重背包)
- android pull解析xml最简单的方法
- 【图论】【二分图匹配】[POJ 3692]Kindergarten
- 【问题及解决】Elasticsearch不能正常启动do not exists on master, act as master failure
- hdu1509 Windows Message Queue
- 在子进程中调用exit()函数对标准I/O流的影响
- HDU 2844:Coins(多重背包)
- 关于android和tomcat
- GID SID AID HID
- Linux Shell 之 Shell中的函数调用
- SQL注入学习笔记(一)
- leetcode 065 —— Valid Number
- VOA 2015-07-26
- 欢迎使用CSDN-markdown编辑器
- 从Trie树(字典树)谈到后缀树