有 NN 件物品和一个容量是 VV 的背包。每件物品只能使用一次。
第 ii 件物品的体积是 vivi,价值是 wiwi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
输入格式
第一行两个整数,N,VN,V,用空格隔开,分别表示物品数量和背包容积。
接下来有 NN 行,每行两个整数 vi,wivi,wi,用空格隔开,分别表示第 ii 件物品的体积和价值。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N,V≤10000<N,V≤1000
0<vi,wi≤10000<vi,wi≤1000
输入样例
4 5
1 2
2 4
3 4
4 5
输出样例:
8
第一种动态规划二维版本:思路:闫式DP分析法:划分为两部分:第一部分:状态表示 f[i][j]:(又分为两步--->)(1)集合:所有的选法和选取条件---->本题只从i个物品中选取,和物品总体积小于等于j(2)属性分为--->最大值,最小值(这个二维有时候需要考虑边界问题,初始化个正无穷就好),数量第二部分是状态计算------>集合的划分:
本题难点分不含i和含i----->不含i用f[i - 1][j],含i用f[i - 1,(j - v[i]) + w[i]]表示
1 #include<iostream> 2 #include<algorithm> 3 4 using namespace std; 5 6 const int N = 1010; 7 8 int n,m; 9 int v[N],w[N]; 10 int f[N][N]; 11 int main(){ 12 cin >> n >> m; 13 for(int i = 1;i <= n;i++) cin >> v[i] >> w[i]; 14 15 //物品的数量和背包体积 16 for(int i = 1;i <= n;i++) 17 for(int j = 0;j <= m;j++) 18 { 19 //不含第i个物品,和含有第i个物品,不含第i个物品一定存在,但是含有第i个物品不一定存在 20 //因为我们加上第i个物品的体积可能会大于我们的背包体积(j < vi),所以右边可能会是空集 21 //第i-1个个物品一定存在,先存到i里边 22 f[i][j] = f[i - 1][j]; 23 //在原有i-1这个物品的数量体积上,在进行判断是否能在装有第i-1物品的体积基础上用我们的第i个物品的体积进行替换 24 //使我们背包的利用率达到最大,也就是进行判断在数量为i的物品背包容量不超过j的情况下,能装的物品的最大价值 25 //是多少 26 //背包体积不超过j的情况下,用上一个价值去和当前价值进行比较 27 //f[i][j] 表示的就是我们背包当前的状态表示 28 if(j >= v[i]) f[i][j] = max(f[i][j],f[i - 1][j - v[i]] + w[i]); 29 } 30 cout << f[n][m]; 31 32 33 }
原文地址:https://www.cnblogs.com/luyuan-chen/p/11615687.html
时间: 2024-11-08 22:40:32