Luogu 1833 樱花

题目链接:https://www.luogu.org/problemnew/show/P1833

思路:

这是一个混合背包问题,即将$01$、完全、多重混合在一起。

我们可以选择分别进行处理。

或者把完全背包的个数用总时间除以单位时间来代表,然后用多重背包统一处理。

代码1:

#include 
const 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:

#include 
const 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;
}

 

转载于:https://www.cnblogs.com/BeyondLimits/p/11165915.html

你可能感兴趣的:(Luogu 1833 樱花)