动态规划小结——背包问题

本文详细介绍了动态规划在解决背包问题中的应用,包括完全背包问题和0-1背包问题。完全背包问题中,每种物品无限,目标是最大化价值。0-1背包问题增加了物品限制,每种仅有一个,同样追求最大价值。文章提供了状态转移方程及相应代码实现,探讨了不同的状态定义对枚举顺序的影响,并讨论了降维优化的可能性。
摘要由CSDN通过智能技术生成

背包问题是动态规划的经典问题,所有初次学习动态规划都会讲述这个经典问题。因此,有必要弄清跟背包问题的所有分析过程并熟练掌握各种类型的代码。

一,完全背包问题

1.问题描述:有n种物品,每种物品有无限多个,第i个物品重量是wi,价值是vi,从这些物品中挑选总重量不超过W的物品,求出挑选物品价值的最大值。

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

2.解题思路:本题类似于“硬币问题”,硬币问题只要求凑够相应的面值,这里只不过多了一个新的属性——价值,即不仅要凑够重量,还要使得价值尽可能大。按照动态规划的分析思路,先定义状态d(j):剩余重量为j时的最大价值。那么如果当前使用了第i个物品(如果可以用的话),状态变转移到j-w[i],而价值变为d[j-w[i]]+v[i],因此状态转移方程如下:

d[j]=max(d[j],d[j-w[i]]+v[i]);(0≤i<n)

这个过程中随着物品的增多,剩余的重量在逐渐减小。

3.代码:

(1)不包含打印路径

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<functional>
using namespace std;

#define maxn 1000
#define rep(i,n) for(int i=0;i<(n);i++)
int d[maxn];
int w[maxn],v[maxn];
int n, W;
int dp(int j)
{
	int&ans = d[j];
	if (ans>0)return ans;
	for (int i = 0; i < n;i++)
	if (j >= w[i])
		ans = max(ans, dp(j-w[i]) + v[i]);
	return ans;
}
int main()
{
	//freopen("test.txt", "r", stdin);
	scanf("%d%d", &n, &W);
	rep(i, n)
		scanf("%d", w + i);
	rep(i, n)
		scanf("%d", v + i);
	dp(W);//从状态W开始,走到状态0
	cout << d[W] << endl;
	return 0;
}

(2)包含打印路径

#define _CRT_SECURE_NO_WARNINGS 
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值