P1833 樱花

爱与愁大神后院里种了n 棵樱花树,每棵都有美学值
爱与愁大神在每天上学前都会来赏花。爱与愁大神可是生物学霸,他懂得如何欣赏樱花:
一种樱花树看一遍过,一种樱花树最多看,一种樱花树可以看无数遍。
但是看每棵樱花树都有一定的时间 。爱与愁大神离去上学的时间只剩下一小会儿了。求解看哪几棵樱花树能使美学值最高且爱与愁大神能准时(或提早)去上学

1. 混合背包问题

int maxval(int v,vector<int>&c,vector<int>&w,vector<int>&cnt){ 
    int n = c.size();
    vector<int> dp(v+1);
    function<void(int,int)> ZeroOnePack = [&](int cost,int weight){ //0-1背包
        for(int j=v;j>=weight;j--)
            dp[j] = max(dp[j],dp[j-weight]+cost);
    };
    function<void((int,int))> CompletePack = [&](int cost,int weight){//完全背包
        for(int j=weight;j<=v;j++)
            dp[j] = max(dp[j],dp[j-weight]+cost);
    };
    function<void((int,int,int))> MutiplePack = [&](int cost,int weight,int cnt){//多重背包
        if(cnt==0||weight*cnt>=v){ //如果质量超过上限,相当于无限个
            CompletePack(cost,weight);
            return;
        }
        int k = 1;
        while(k<cnt){
            ZeroOnePack(k*cost,k*weight);
            cnt-=k;
            k*=2;
        }
        ZeroOnePack(cnt*cost,cnt*weight);
    };

    int res = 0;
    for(int i=0;i<n;i++)//遍历n中树
        MutiplePack(w[i],c[i],cnt[i]);
    for(int j=0;j<=v;j++)
        res = max(res,dp[j]);
    return res;
}

int time_trans(string time){
    stringstream ss(time);
    int hours, minutes;
    char delimiter;
    ss >> hours >> delimiter >>noskipws >> minutes;
    return hours*60 + minutes;
}


int main()
{
    string start,end;
    int v; int n;
    cin>>start>>end>>n;
    v = time_trans(end)-time_trans(start);
    vector<int> c(n);
    vector<int> w(n);
    vector<int> cnt(n);
    for(int i=0;i<c.size();i++)
        cin>>c[i]>>w[i]>>cnt[i];
    cout<<maxval(v,c,w,cnt);
    return 0;
}
posted @ 2023-08-24 00:52  失控D大白兔  阅读(6)  评论(0编辑  收藏  举报