HDOJ 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(完全背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2191
多重背包,转化成0/1背包来做,不过转化成1个1个效率很低,可以按1 2 4 8 16....这样的数列来分,根据二进制的原理,这样可以表示任何数
例如 13可以表示成 1 +4 +8
AC代码:
/*HDOj2191 作者:陈佳润 2013-04-18 */ #include<iostream> #include<string.h> using namespace std; #define max(a,b) (a>b?a:b) int n; int dp[105]; void ZeroOnePack(int value,int weight){//0/1背包 int i; for(i=n;i>=weight;i--){ dp[i]=max(dp[i],dp[i-weight]+value); } } int main(){ int Time,t,i,m,a,b,num; cin>>Time; while(Time--){ cin>>n>>m; memset(dp,0,sizeof(dp)); for(i=1;i<=m;i++){ cin>>a>>b>>num; t=1; while(num){//转化成0/1背包 if(num>=t){ ZeroOnePack(t*b,t*a); num-=t; t=t*2; } else{ ZeroOnePack(num*b,num*a); num=0; } } } cout<<dp[n]<<endl; } return 0; }