完全背包(dp专题)

学习了01背包,现在进一步探讨递推关系,完全背包问题

题目:有n种重量和价值分别为wi,vi的物品,从这些物品种选出总重量不超过W的物品,求出挑选物品价值总和的最大值。在这里,每种物品可以挑选任意多件

限制条件:1<=n<=100,1<=wi,vi<=100,1<=W<=10000

输入:n=3   (w,v)=((3,4),(4,5),(2,3)) W=7

输出:10

和01背包相比,这次同一种类的物品可以选择任意多件。 我们试着写出递推关系

令dp[i+1[j]:=从第i个物品到第n-1个物品中挑选总总量不超过j时总价值的最大值。 那么递推关系为:

dp[i][j]=max(dp[i][j],dp[i+1][j-k*w[i]]+k*v[i])

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<set>
typedef long long ll;
using namespace std;
int n,m;
int dp[1100][1100];
int w[1100],v[1100];
int main()
{
    memset(dp,0,sizeof(dp));
    int n,m;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    scanf("%d%d",&w[i],&v[i]);
    scanf("%d",&m);
    for(int i=n-1;i>=0;i--)
    {
        for(int j=0;j<=m;j++)
        {
            for(int k=0;k*w[i]<=j;k++)
            {
                dp[i][j]=max(dp[i][j],dp[i+1][j-k*w[i]]+k*v[i]);
            }
        }
    }
    printf("%d\n",dp[0][m]);
    return 0;
}

  上面一种算法有三重循环,复杂度可能达到(n*m*m),这样并不够好,其实在这里有重复的计算

在dp[i+1][j]的计算中选择

猜你喜欢

转载自www.cnblogs.com/caijiaming/p/9282821.html