完全背包从01背包演化而来:
dp[i][j]背包空间为j时前i件物品
一式:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i],dp[i-1][j-2*w[i]]+2*v[i],,,,dp[i-1][j-n*w[i]]+n*v[i])
不放 , 放一件 ,放两件 ,,, 放n件
二式:dp[i][j-w[i]]=max(dp[i-1][j-w[i]],dp[i-1][j-2*w[i]]+v[i],dp[i-1][j-3*w[i]]+2*v[i],,,,,,, dp[i-1][j-n*w[i]]+ (n-1)*v[i])
假设背包空间为j-w[i] 得到dp[i][j-w[i]]的表达式, 两边再同时加上v[i] 得到三式:
三式: dp[i][j-w[i]]+v[i]=max(dp[i-1][j-w[i]]+v[i],dp[i-1][j-2*w[i]]+2*v[i],dp[i-1][j-3*w[i]]+3*v[i],,,, ,,, dp[i-1][j-n*w[i]]+n*v[i])
用三式替代一式中的 max 括号内后n项
即dp[i-1][j-w[i]]+v[i],dp[i-1][j-2*w[i]]+2*v[i],,,,dp[i-1][j-n*w[i]]+n*v[i]
得到状态转移方程:
dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]]+v[i])
代码:
#include <iostream>
using namespace std;
int dp[100][100];
int main ()
{
  //  freopen("in.txt","r",stdin);
    int n;
    int weight;
    cin>>n>>weight;
    int w[n+1];
    int v[n+1];
    int i,j;
    for(i=1;i<=n;i++)
    {
        cin>>w[i]>>v[i];
    }
    /*
4 5
1 2
2 4
3 4
4 5*/
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=weight;j++)
        {
            if(j<w[i])
            {
                dp[i][j]=dp[i-1][j];
            }
            else
            {
                dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]]+v[i]);
            }
        }
    }
    cout<<dp[n][weight];
    return 0;
}
 
输入:
2 11
 2 3
 6 14
输出:20









