0
点赞
收藏
分享

微信扫一扫

dp 完全背包模板

_刘彦辉 2022-02-05 阅读 55

完全背包从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

举报

相关推荐

0 条评论