题目链接:https://www.luogu.org/problemnew/show/P1833
思路:
这是一个混合背包问题,即将$01$、完全、多重混合在一起。
我们可以选择分别进行处理。
或者把完全背包的个数用总时间除以单位时间来代表,然后用多重背包统一处理。
代码1:
#includeconst int MAXN=20050; using namespace std; int t1,t2,t3,t4,n,T,t[MAXN],c[MAXN],p[MAXN],f[MAXN]; char c1,c2; void f1(int tt,int cc){ for(int j=T;j>=tt;j--) f[j]=max(f[j],f[j-tt]+cc); } void f2(int tt,int cc){ for(int j=tt;j<=T;j++) f[j]=max(f[j],f[j-tt]+cc); } void f3(int tt,int cc,int pp){ for(int i=1;pp;i<<=1){ if(i>pp) i=pp; pp-=i; f1(i*tt,i*cc); } } int main(){ scanf("%d %c %d %d %c %d %d",&t1,&c1,&t2,&t3,&c2,&t4,&n); T=(t3-t1)*60+t4-t2; for(int i=1;i<=n;i++) cin>>t[i]>>c[i]>>p[i]; for(int i=1;i<=n;i++){ if(p[i]==1) f1(t[i],c[i]); else if(p[i]==0) f2(t[i],c[i]); else f3(t[i],c[i],p[i]); } cout< endl; return 0; }
代码2:
#includeconst int MAXN=1000050; using namespace std; int n,t1,t2,t3,t4,t[MAXN],dif,c[MAXN],p,num[MAXN],f[MAXN]; char c1,c2; int main(){ scanf("%d%c%d%d%c%d%d",&t1,&c1,&t2,&t3,&c2,&t4,&n); //printf("%d%c%d%d%c%d%d",t1,c1,t2,t3,c2,t4,n); dif=abs(t1-t3)*60+t4-t2; for(int i=1;i<=n;i++){ cin>>t[i]>>c[i]>>p; if(p==0) num[i]=dif/t[i]; else num[i]=p; } for(int i=1;i<=n;i++){ for(int j=1;num[i];j<<=1){ if(num[i] num[i]; num[i]-=j; for(int l=dif;l>=j*t[i];l--) f[l]=max(f[l],f[l-j*t[i]]+j*c[i]); } } cout< endl; return 0; }