分析:有资金n元,而市场有m种大米,每种大米价格不等,重量不等,数量不等,
并且只能整袋购买。如何用有限的资金最多能采购多少公斤粮食呢?
在这里价格相当与传统多重背包的“花费”而重量是“价值”。
dp[j]=max{ dp[j-k*c[i]+w[i]] | 0<=k<=n[i] }
这里将多重背包转换为01背包和完全背包。
#include<stdio.h>
#include<string.h>
int dp[110],n;
void ZeroOnePack(int cost,int weight)
{
for(int j=n;j>=cost;j--)
dp[j]=dp[j]>dp[j-cost]+weight?dp[j]:dp[j-cost]+weight;
}
void ComplelePack(int cost,int weight)
{
for(int j=cost;j<=n;j++)
dp[j]=dp[j]>dp[j-cost]+weight?dp[j]:dp[j-cost]+weight;
}
void MultiplePack(int cost,int weight,int amount)
{
if(cost*amount>n)
{
ComplelePack(cost,weight);
return;
}
int k=1;
while (k<=amount)
{
ZeroOnePack(k*cost,k*weight);
amount-=k;
k*=2;
}
ZeroOnePack(amount*cost,amount*weight);
}
int main()
{
int C,m,p[102],h[102],num[102];
scanf("%d",&C);
while (C--)
{
//读取数据
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&p[i],&h[i],&num[i]);
//初始化 不需要“装满”
memset(dp,0,sizeof(dp));
//多重背包问题
for(int i=1;i<=m;i++)
MultiplePack(p[i],h[i],num[i]);
printf("%d
",dp[n]);
}
return 0;
}