背包问题基本解法

时间:2021-05-07 18:42:00

① 01背包

有n件物品和一个容量为v的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。

这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t,n,v,i,j,w[1005],c[1005],dp[1005];
    cin>>t;
    while(t--)
    {
        memset(dp,0,sizeof dp);
        cin>>n>>v;
        for(i=1;i<=n;i++)
            scanf("%d",&c[i]);
        for(i=1;i<=n;i++)
            scanf("%d",&w[i]);
for(i=1;i<=n;i++) for(j=v;j>=w[i];j--) dp[j]=max(dp[j],dp[j-w[i]]+c[i]); cout<<dp[v]<<endl; } return 0; }

 ② 完全背包

有n种物品和一个容量为v的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t,n,v,i,j,w[1005],c[1005],dp[1005];
    cin>>t;
    while(t--)
    {
        memset(dp,0,sizeof dp);
        cin>>n>>v;
        for(i=1;i<=n;i++)
            scanf("%d",&c[i]);
        for(i=1;i<=n;i++)
            scanf("%d",&w[i]);
            
        for(i=1;i<=n;i++)
            for(j=w[i];j<=v;j++)
                dp[j]=max(dp[j],dp[j-w[i]]+c[i]); 
        
        cout<<dp[v]<<endl;
    }
    return 0;
}

 ③ 多重背包

有n种物品和一个容量为v的背包。第i种物品最多有num[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main()  
{  
    int t,v,n,i,j,k,dp[105],num[105],c[105],w[105];
    cin>>t;
    while(t--)
    {
        memset(dp,0,sizeof dp);
        cin>>n>>v;
        for(i=1;i<=n;i++)
            scanf("%d%d%d",&c[i],&w[i],&num[i]);
        
        for(i=1;i<=n;i++)
            for(j=1;j<=num[i];j++)
                for(k=v;k>=c[i];k--)
                    dp[k]=max(dp[k],dp[k-c[i]]+w[i]);
        
        cout<<dp[v]<<endl;
    }
    return 0;  
}