【51Nod 1086】背包问题 V2
2016-10-24 20:29
309 查看
Description
有N种物品,每种物品的数量为C1,C2……Cn。从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数)。求背包能够容纳的最大价值。Solution
这是一个经典的有限背包问题,但是它需要优化复杂度。他用到了一个很奇妙也很机智的思想:每个数可以用二进制来表示。
二进制优化
因为每个数的个数如果逐个枚举的话,那么会有很多冗余的状态。每个数可以拆成:1+2+4+…+(m-sum)
每次直接用上面的数字的个数来转移就好了。
为什么可以这样呢?因为一个数可以表示为二进制,那么就是说可以有好多个二的次幂加起来。
时间复杂度优化到O(nmlog(m))
Code
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define fo(i,a,b) for(i=a;i<=b;i++) #define fod(i,a,b) for(i=a;i>=b;i--) using namespace std; typedef long long ll; const int maxn=107,mxx=50007; ll i,j,k,l,t,n,m,ans; ll w,p,c,f[mxx]; int main(){ scanf("%d%d",&n,&m); fo(i,1,n){ scanf("%lld%lld%lld",&w,&p,&c); for(j=1;j<=c;c-=j,j*=2){ fod(k,m,j*w){ f[k]=max(f[k],f[k-j*w]+j*p); } } if(!c)continue; fod(k,m,c*w){ f[k]=max(f[k],f[k-c*w]+c*p); } } fod(i,m,0)ans=max(ans,f[i]); printf("%lld\n",ans); }
相关文章推荐
- 51nod 1086 背包问题 V2
- 51Nod 1086背包问题V2
- 51nod 1086 背包问题V2 (巧妙dp,二进制)
- 51nod 1086 背包问题 V2 (多重背包二进制优化)
- 51nod 1086 背包问题 V2
- 51Nod 1086 背包问题 V2(多重背包)
- 【多重背包】51nod 1086 背包问题 V2
- 51NOD-1086 背包问题 V2
- 51Nod 1086 背包问题 V2(二进制多重背包)
- 51Nod:1086背包问题 V2
- 51nod 1086 背包问题 V2(多重背包)
- 51nod 1086 背包问题 V2 (多重背包问题)
- 51Nod 1086 背包问题 V2(二进制多重背包)
- 51nod 1086 背包问题V2(巧妙拆分多重背包)
- 51nod 1086 背包问题V2 动态规划
- 51Nod-1086-背包问题 V2
- 51nod 1086 背包问题 V2(多重背包问题)
- 51nod 1086 背包问题 V2
- 51nod 1086 背包问题 V2(多重背包)
- 51NOD-1086 背包问题 V2(多重背包)