看似是完全背包,01背包,分组背包的混合,,其实可以用二进制数拆分之后转化成简单的01背包问题。
状态转移方程比较好写,就用01背包的就行,关键在于拆分的细节
#include <bits/stdc++.h>
using namespace std;
int m,n,cnt=0;
int v[1005000],w[1005000];
int dp[1005000];
int main()
{
int a1,b1,a2,b2,a,b,c;
char s;
cin>>a1>>s>>b1;
cin>>a2>>s>>b2;
int t=a2-a1;
if(t<0)t+=24;
int t_=b2-b1;
if(t_<0)t_+=60,t--;
m=60*t+t_; //算出拥有的时间
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a>>b>>c;
if(!c)c=999999;
int k=1;
while(k<=c)
{
w[++cnt]=k*a;
v[cnt]=k*b;
c-=k;
k*=2;
}
if(c>0)w[++cnt]=c*a,v[cnt]=c*b; //拆完还有剩下的,单独装一份
}
for(int i=1;i<=cnt;i++)
{
for(int j=m;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]); //01背包的状态转移方程
}
cout<<dp[m]<<endl;
return 0;
}