没错 这就是基础题 我基础弱orz orz
今天才知道的这道题做法 orz orz
混合背包相比01和完全
就是多了个分类讨论
如果个数*体积超过空间
就作完全背包处理
否则二进制拆分作01处理
今天才知道的这道题做法 orz orz
混合背包相比01和完全
就是多了个分类讨论
如果个数*体积超过空间
就作完全背包处理
否则二进制拆分作01处理
只是注意二进制拆分后还要扫尾一次01
#include<cstdio>
#define loop(i,j,k) for(int i=j;i<=k;i++)
#define down_loop(i,j,k) for(int i=k;i>=j;i--)
#define max(a,b) a>b?a:b
#define MAXM (200000+10)
#define MAXN (200+10)
using namespace std;
int n,m;
int dp[MAXM];
int w[MAXN];
int v[MAXN];
int num[MAXN];
void readdata()
{
scanf("%d%d",&n,&m);
loop(i,1,n)
{
scanf("%d%d%d",&v[i],&w[i],&num[i]);
num[i]=num[i]==-1?m/v[i]+5:num[i];
}
}
void completebag(int i)
{
loop(j,v[i],m)
dp[j]=max(dp[j-v[i]]+w[i],dp[j]);
}
void zeroonebag(int vv,int ww)
{
down_loop(j,vv,m)
dp[j]=max(dp[j-vv]+ww,dp[j]);
}
void solve()
{
loop(i,1,n)
{
if(num[i]*v[i]>=m)
completebag(i);
else
{
int k=1;
int count=num[i];
while(k<=count)
{
zeroonebag(k*v[i],k*w[i]);
count-=k;
k*=2;
}
if(count!=0)
zeroonebag(count*v[i],count*w[i]);
}
}
}
int main()
{
readdata();
solve();
printf("%d",dp[m]);
}