学习了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]的计算中选择