洛谷P1833樱花
思路:
01背包,完全背包和多重背包的混合,分别判断一下就行了。
代码:
#include<bits/stdc++.h>
const int N=1e4+10;
const int mod=1e7+9;
const int maxn=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
const int inf=99999999;
using namespace std;
int w[N],v[N],p[N],dp[N]={0};
int main()
{
int bh,bm,eh,em,sum,n,i,j,k;
scanf("%d:%d%d:%d%d",&bh,&bm,&eh,&em,&n);
sum=(eh*60+em)-(bh*60+bm);
for(i=1;i<=n;i++)
scanf("%d%d%d",&w[i],&v[i],&p[i]);
for(i=1;i<=n;i++)
{
if(p[i]==0)
for(j=w[i];j<=sum;j++)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
else if(p[i]==1)
for(j=sum;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
else
{
int num=min(p[i],sum/w[i]);
for(j=1;num>0;j<<=1)
{
if(j>num)
j=num;
num-=j;
for(k=sum;k>=j*w[i];k--)
dp[k]=max(dp[k],dp[k-j*w[i]]+j*v[i]);
}
}
}
printf("%d\n",dp[sum]);
return 0;
}