• 混合背包 洛谷P1833 樱花


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

    题意:有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包),应该怎么求解。

    分析:这个题其实一点都不难,之所以写题解是提醒自己记住这个写法,直接根据一个物品的数量判断是什么背包,然后直接写那个背包的写法即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    const int inf=1<<30;
    const int maxn=1e4+7;
    int dp[maxn],q[maxn],pa[maxn];
    int main(){
        int h1,h2,m1,m2,V;
        scanf("%d:%d",&h1,&m1);scanf("%d:%d",&h2,&m2);
        if(h1==h2) V=m2-m1;
        else V=(h2-h1-1)*60+m2+60-m1;
        int v,w,p;
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&w,&v,&p);
            if(p==0){
                for(int j=w;j<=V;j++){
                    dp[j]=max(dp[j],dp[j-w]+v);
                }
            }
            else if(p==1){
                for(int j=V;j>=w;j--){
                    dp[j]=max(dp[j],dp[j-w]+v);
                }
            }
            else {
                p=min(p,V/w);
                for(int d=0;d<w;d++){
                    int tail=0,head=0;
                    int k=(V-d)/w;
                    for(int j=0;j<=k;j++){
                        while(head<tail&&dp[d+j*w]-j*v>=q[tail-1]) tail--;
                        q[tail]=dp[d+j*w]-j*v;pa[tail++]=j;
                        while(head<tail&&pa[head]<j-p) head++;
                        dp[d+j*w]=max(dp[d+j*w],q[head]+j*v);
                    }
                }
            }
        }
        cout<<dp[V]<<endl;
        return 0;
    } 
  • 相关阅读:
    C语言实现的单链表
    单链表创建链表出现问题
    Windows10更新后出现右击文件卡死
    顺序表的错误
    XML 字符串 转 JSON
    xml to json
    excel xlsx-js 细节链接
    关于javasciprt导出excel 一
    关于javasciprt导出excel 前言
    书签8
  • 原文地址:https://www.cnblogs.com/qingjiuling/p/11354772.html
Copyright © 2020-2023  润新知