混合背包

混合背包就是指,既有01背包,完全背包,多重背包。
解法很简单,就是对第二层for循环分情况讨论。
直接来题吧
此处多重背包使用二进制优化算法,当然也可以使用单调队列进行优化
详见 https://www.cnblogs.com/kingbuffalo/p/16285929.html
题:https://www.luogu.com.cn/problem/P1833
ac代码如下

#define NMAX 1005
int dp[NMAX];

int main(){
    int sh,sm;
    int eh,em;
    int n;
    scanf("%d:%d",&sh,&sm);
    scanf("%d:%d",&eh,&em);
    scanf("%d",&n);
    int tm = (eh-sh) * 60 + em-sm;
    int t,c,p;
    for(int i=0;i<n;++i){
        scanf("%d%d%d",&t,&c,&p);
        if ( p == 0 ){
            for(int j=t;j<=tm;++j){
                dp[j] = max(dp[j],dp[j-t]+c);
            }
        }else if ( p == 1 ){
            for(int j=tm;j>=t;--j){
                dp[j] = max(dp[j],dp[j-t]+c);
            }
        }else{
            //多重背包使用二进制优化,一般情况下过得了。
            int times = 1;
            while(p>=times){
                for(int j=tm;j>=t*times;--j){
                    dp[j] = max(dp[j],dp[j-t*times]+times*c);
                }
                p-=times;
                times *= 2;
            }
            if ( p ){
                for(int j=tm;j>=t*p;--j){
                    dp[j] = max(dp[j],dp[j-t*p]+c*p);
                }
            }
        }
    }
    printf("%d\n",dp[tm]);

    return 0;
}
posted @ 2022-06-09 15:30  传说中的水牛  阅读(131)  评论(0编辑  收藏  举报