题目链接https://www.luogu.com.cn/problem/P1833
多重背包的模版 但是多了一种无限多的物品
先看多重背包模版
for(int i = 0; i < weight.size(); i++) { // 遍历物品
for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量
// 以上为01背包,然后加一个遍历个数
for (int k = 1; k <= nums[i] && (j - k * weight[i]) >= 0; k++) { // 遍历个数
dp[j] = max(dp[j], dp[j - k * weight[i]] + k * value[i]);
}
}
在遍历多个物品时可以将遍历个数,和01背包相同,只是遍历时多一重循环判断是否选择多个物品,其实多个物品打包起来就是一个物品,和01背包是一样的。
那么无限个物品也就很好表示了将第三重循环的k <= nums[i]删掉,就表示物品数目没有限制了。
AC代码如下
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
char t1[6],t2[6];
int weight[10002];
int value[10002];
int num[10002];
int dp[10002];
int main()
{
scanf("%s%s",t1,t2);
int t1h=0,t1m=0,t2h=0,t2m=0,n;
if('0'<=t1[1]&&t1[1]<='9')
{
t1h=(t1[0]-'0')*10+t1[1]-'0';
t1m=(t1[3]-'0')*10+t1[4]-'0';
}
else
{
t1h=t1[0]-'0';
t1m=(t1[2]-'0')*10+t1[3]-'0';
}
if('0'<=t2[1]&&t2[1]<='9')
{
t2h=(t2[0]-'0')*10+t2[1]-'0';
t2m=(t2[3]-'0')*10+t2[4]-'0';
}
else
{
t2h=t2[0]-'0';
t2m=(t2[2]-'0')*10+t2[3]-'0';
}
int bagweight=(t2h-t1h)*60+t2m-t1m;//将时间转化成背包容量
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&weight[i],&value[i],&num[i]);
for(int i=1;i<=n;i++)
for(int j=bagweight;j>=weight[i];j--)
{
if(num[i]!=0)//有限个
{
for(int k=1;(j-k*weight[i])>=0 && k<=num[i]; k++ )
{
dp[j]=max(dp[j],dp[j-k*weight[i]]+k*value[i]);
}
}
else//无限个
{
for(int k=1;(j-k*weight[i])>=0 ; k++ )
{
dp[j]=max(dp[j],dp[j-k*weight[i]]+k*value[i]);
}
}
}
cout<<dp[bagweight];
return 0;
}