题目传送门
题意:给n件物品和一个容积为V的背包,有些物品只可以拿一次,有些物品可以无限拿,有些物品可拿规定的次数,问你在背包容量内,可获得最大的价值是多少。
思路:把不同的物品种类分开处理即可。注意多重背包应该使用二进制优化与01背包视为同类处理,否则TLE
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const int mod=1e9+7;
const int INF=0x7fffffff;
const ll LLINF=0x7fffffffffffffff;
const double EPS=1e-10;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define debug cout<<"debug"<<endl;
#define ls p<<1
#define rs p<<1|1
//#define int long long
struct node
{
int v,w,s;
}a[N];
int dp[N];
signed main()
{
IOS;
//freopen("","r",stdin);
//freopen("","w",stdout);
int n,V;
cin>>n>>V;
int cnt=0;
for(int i=1;i<=n;i++)
{
int v,w,s;
cin>>v>>w>>s;
if(s==0||s==-1)
{
a[++cnt].v=v;
a[cnt].w=w;
a[cnt].s=s;
}
else
{
int t=1;
while(t<=s)
{
a[++cnt].w=t*w;
a[cnt].v=t*v;
a[cnt].s=-1;
s-=t;
t*=2;
}
a[++cnt].w=w*s;
a[cnt].v=v*s;
a[cnt].s=-1;
}
}
for(int i=1;i<=cnt;i++)
{
if(a[i].s==-1)
{
for(int j=V;j>=a[i].v;j--)
{
dp[j]=max(dp[j],dp[j-a[i].v]+a[i].w);
}
}
else
{
for(int j=a[i].v;j<=V;j++)
{
dp[j]=max(dp[j],dp[j-a[i].v]+a[i].w);
}
}
}
cout<<dp[V];
}