/*今天刚看了背包九讲的多重背包优化,经典啊!
将n[i]件等值的物品用二进制转化为log(n)件物品,这个是个很大的优化,
具体的处理是对每一件物品的费用和价值也都乘上相应的二进制系数。*/
#include <stdio.h>
#include <cstring>
int p[101],c[101],h[101];
int dp[101];
int n;
int max(int a,int b)
{
if(a>b) return a;
else return b;
}
inline void zero(int val,int cost)
{
for(int i=n; i>=cost; i--)
dp[i]=max(dp[i],dp[i-cost]+val);
}
inline void complete(int val,int cost)
{
for(int i=cost; i<=n; i++)
dp[i]=max(dp[i],dp[i-cost]+val);
}
inline void multiply(int cost,int weight,int amount)
{
if(cost*amount>=n)
{
complete(weight,cost);
return ;
}
for(int i=1; i<amount; i*=2)
{
zero(weight*i,cost*i);
amount-=i;
}
zero(amount*weight,amount*cost);
}
int main()
{
int m,test;
scanf("%d",&test);
while(test--)
{
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
for(int i=0; i<m; i++) scanf("%d%d%d",&p[i],&h[i],&c[i]);
for(int i=0; i<m; i++)
multiply(p[i],h[i],c[i]);
printf("%d\n",dp[n]);
}
return 0;
}
//下面是直接转为01背包,不加二进制优化,时间复杂度显而易见的差距。
#include <stdio.h>
#include <cstring>
int max(int a,int b)
{
if(a>b) return a;
else return b;
}
int p[101],h[101],c[101];
int dp[101];
int main()
{
int n,m,test;
scanf("%d",&test);
while(test--)
{
scanf("%d%d",&n,&m);
for(int i=0; i<m; i++) scanf("%d%d%d",&p[i],&h[i],&c[i]);
memset(dp,0,sizeof(dp));
int mm=-1;
for(int i=0; i<m; i++)
for(int j=0; j<c[i]; j++)
for(int k=n; k>=p[i]; k--)
{
dp[k]=max(dp[k],dp[k-p[i]]+h[i]);
if(dp[k]>mm) mm=dp[k];
}
printf("%d\n",mm);
}
return 0;
}