01背包
二维可以用一维滚动数组优化,只能选一个每个物品只有选和不选两种情况。

#include<iostream>
using namespace std;
const   int N=1010;
int f[N];
int w[N];
int v[N]; int main()
{
   
    int n,v1;
    cin>>n>>v1;
    for(int i=1;i<=n;i++)
    cin>>v[i]>>w[i];
    for(int i=1;i<=n;i++)
    for(int j=v1;j>=v[i];j--)
    f[j]=max(f[j],f[j-v[i]]+w[i]);
    cout<<f[v1]<<endl;
    return 0;
}

完全背包问题
也可以用滚动数组来算
状态转移方程可以更新为dp[i][j]=dp[i-1][j]和dp[i][j-v]+w

#include<iostream>
using namespace std;
const   int N=1010;
int f[N];
int w[N];
int v[N]; int main()
{
   
    int n,v1;
    cin>>n>>v1;
    for(int i=1;i<=n;i++)
    cin>>v[i]>>w[i];
    for(int i=1;i<=n;i++)
    for(int j=v[i];j<=v1;j++)
    f[j]=max(f[j],f[j-v[i]]+w[i]);
    cout<<f[v1]<<endl;
    return 0;
}

多重背包问题
每个物品有限定的个数可以选,问最大价值
要是暴力做n3的复杂度,用二进制优化,将每个数的数量分成logs个,可以用化成nlogs的复杂度。把每堆物品打包,最后当成01背包做。

#include<iostream>
using namespace std;
const   int N=1110;
int f[N];
int s[N];
int v[N],w[N]; int main()
{
   
        int n,v1;
        cin>>n>>v1;
    for(int i=1;i<=n;i++)
    {
   
        cin>>v[i]>>w[i]>>s[i];
    }
    int cnt=1;
    for(int i=1;i<=n;i++)
    {
   
        int k=1;
        int s1=s[i]; while(k<=s1)
        {
   
            v[cnt]=k*v[i];
            w[cnt]=k*w[i];
            cnt++;
            s1-=k;
            k*=2;
        }
        if(s1)
        {
   
            v[cnt]=s1*v[i];
            w[cnt]=s1*w[i];
            cnt++;
        }
    }
    n=cnt;
    for(int i=1;i<=n;i++)
    for(int j=v1;j>=v[i];j--)
    f[j]=max(f[j],f[j-v[i]]+w[i]);
    cout<<f[v1]<<endl;
    return 0;
}

分组背包问题
每个组里的物品只能选一个,这就需要用一个二维的数组w,v分别存放每组物品的价值和空间。

#include<bits/stdc++.h>
using namespace std;
const   int N=110;
int f[N];
int w[N][N],v[N][N];
int s[N]; int main()
{
   
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
   
        cin>>s[i];
        for(int j=0;j<s[i];j++)
        {
   
            cin>>v[i][j]>>w[i][j];
        }
    }
    for(int i=1;i<=n;i++)
     for(int k=m;k>=0;k--)
    for(int j=0;j<s[i];j++)
     if(k>=v[i][j])
      f[k]=max(f[k],f[k-v[i][j]]+w[i][j]);
      cout<<f[m]<<endl;
    return 0;
}