背包

记录一下背包的各种模板

① 01背包

题目链接:https://www.acwing.com/problem/content/2/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
using namespace std;
int dp[1005];
int main ()
{
    int n,m,i,t,j,k,v,v1,w;
    cin>>n>>v;
    for(i=1;i<=n;++i)
    {
        cin>>v1>>w;
        for(t=v;t>=v1;--t)
                dp[t]=max(w+dp[t-v1],dp[t]);
    }
    cout<<dp[v]<<endl;
    return 0;
}

②完全背包

题目链接:https://www.acwing.com/problem/content/3/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
using namespace std;
int dp[1005];
int main ()
{
    int n,m,i,t,j,k,v,v1,w;
    cin>>n>>v;
    for(i=1;i<=n;++i)
    {
        cin>>v1>>w;
        for(t=v1;t<=v;++t)
                dp[t]=max(w+dp[t-v1],dp[t]);
    }
    cout<<dp[v]<<endl;
    return 0;
}

③多重背包Ⅰ

题目链接:https://www.acwing.com/problem/content/4/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
using namespace std;
int dp[1005];
int main ()
{
    int n,m,i,t,j,k,v,v1,w;
    cin>>n>>v;
    for(i=1;i<=n;++i)
    {
        cin>>v1>>w>>j;
        for(t=v;t>=v1;--t)
            for(k=1;k<=j&&k*v1<=t;++k)
            dp[t]=max(k*w+dp[t-k*v1],dp[t]);
    }
    cout<<dp[v]<<endl;
    return 0;
}

④多重背包Ⅱ

题目链接:https://www.acwing.com/problem/content/5/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#include <vector>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
using namespace std;
int dp[2005];
struct node {
int v,w;
};
vector<node> pp;
int main ()
{
    int n,m,i,t,j,k,v,v1,w,p;
    cin>>n>>v;
    for(i=1;i<=n;++i)
    {
        cin>>v1>>w>>j;
        for(t=1;t<=j;t<<=1){
            pp.push_back({t*v1,t*w});
            j-=t;
        }
        if(j>0)
            pp.push_back({j*v1,j*w});
    }
        m=pp.size();
        for(int h=0;h<m;++h)
        for(t=v;t>=pp[h].v;--t)
            dp[t]=max(pp[h].w+dp[t-pp[h].v],dp[t]);
    
    cout<<dp[v]<<endl;
    return 0;
}

⑤多重背包Ⅲ

题目链接:https://www.acwing.com/problem/content/6/

代码待补_(:з)∠)_

⑥混合背包

题目链接:https://www.acwing.com/problem/content/7/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
using namespace std;
int dp[1005];
struct node {
int s,v,w;
};
vector<node> pp;
int main ()
{
    int n,m,i,t,j,k,v1,w,s1,v;
    cin>>n>>v;
    for(i=0;i<n;++i)
    {
        cin>>v1>>w>>s1;
        if(s1<=0)
            pp.push_back({s1,v1,w});
        else
        {
            for(j=1;j<=s1;j<<=1)
            {
                pp.push_back({1,j*v1,j*w});
                s1-=j;
            }
            if(s1)
                pp.push_back({1,s1*v1,s1*w});
        }
    }
    m=pp.size();
    for(i=0;i<m;++i)
    {
        if(pp[i].s==0)
        {
            for(j=pp[i].v;j<=v;++j)
                dp[j]=max(dp[j],dp[j-pp[i].v]+pp[i].w);
        }
        else
        {
            for(j=v;j>=pp[i].v;--j)
                dp[j]=max(dp[j],dp[j-pp[i].v]+pp[i].w);
        }
    }
    cout<<dp[v]<<endl;

    return 0;
}

⑦二维费用的背包问题

题目链接:https://www.acwing.com/problem/content/8/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
using namespace std;
int dp[1005][1005];
int main ()
{
    int n,m,i,t,j,k,v,v1,m1,w;
    cin>>n>>v>>m;
    while(n--)
    {
        cin>>v1>>m1>>w;
        for(i=v;i>=v1;--i)
            for(j=m;j>=m1;--j)
            dp[i][j]=max(dp[i][j],w+dp[i-v1][j-m1]);
    }
    cout<<dp[v][m]<<endl;
    return 0;
}

⑧分组背包

题目链接: https://www.acwing.com/problem/content/9/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
using namespace std;
int dp[1005],v1[105],w[105];
int main ()
{
    int n,m,i,t,j,k,v,s;
    cin>>n>>v;
    while(n--)
    {
        cin>>s;
        for(i=1;i<=s;++i)
            cin>>v1[i]>>w[i];

        for(t=v;t>=0;--t)
            for(i=1;i<=s;++i)
            if(t>=v1[i])
                dp[t]=max(dp[t],dp[t-v1[i]]+w[i]);

    }
    cout<<dp[v]<<endl;
    return 0;
}

⑨有依赖的背包

链接:https://www.acwing.com/problem/content/10/

待补

⑩背包问题求方案数

链接:https://www.acwing.com/problem/content/11/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
#define mod 1000000007
using namespace std;
int dp[1005],res[1005];
int main ()
{
    int n,m,i,t,j,k,v,v1,w;
    cin>>n>>v;
    res[0]=1;
    while(n--)
    {
        cin>>v1>>w;
        for(i=v;i>=v1;--i)
            if(dp[i]<dp[i-v1]+w)
            {
                dp[i]=dp[i-v1]+w;
                res[i]=res[i-v1];
            }
            else if(dp[i]==dp[i-v1]+w)
            {
                res[i]=res[i]+res[i-v1];
                res[i]%=mod;
            }
    }
    int maxs=-1;
    for(i=0;i<=v;++i)
        //cout<<dp[i]<<endl;
        maxs=max(maxs,dp[i]);
    int sum=0;
    for(i=0;i<=v;++i)
        if(maxs==dp[i])
            sum+=res[i];
    cout<<sum<<endl;
    return 0;
}

11 背包问题求具体方案

题目链接:https://www.acwing.com/problem/content/12/

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <cmath>
#define ll long long
#define pi 3.1415927
#define inf 0x3f3f3f3f
using namespace std;
int dp[1005][1005];
int v1[1005],w[1005];
int main ()
{
    int n,m,i,t,j,k,v;
    cin>>n>>v;
    for(i=1;i<=n;++i)
        cin>>v1[i]>>w[i];
    for(i=n;i>=1;--i)
        for(t=0;t<=v;++t)
    {
        if(t>=v1[i])
            dp[i][t]=max(dp[i+1][t],dp[i+1][t-v1[i]]+w[i]);
        else
            dp[i][t]=dp[i+1][t];
    }
    int temp=v;
    for(i=1;i<=n;++i)
    {
        if(temp>=v1[i] && dp[i][temp]==dp[i+1][temp-v1[i]]+w[i] )
        {
            cout<<i<<" ";
            temp-=v1[i];
        }
    }
    cout<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/blowhail/p/11284214.html