浅谈动态规划(01背包问题)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44771588/article/details/102633828

一、 背景:可能许多人认为动态规划这种东西是特别高级的算法,于是心中把这种算法捧上了天,心中对动态规划产生忌惮。这篇文章晚上闲着没事干,单纯依靠自己头脑记忆敲出来的。不夹杂书中枯燥无味的原理。
二、 动态规划概叙:动态规划又叫做 “填表法”,所谓 ”填表“ 就是表面意思,给你一个表来填。编程角度上讲就是给二维数组赋值(此处二维只是个例子,并不是所有的表都是二维)。表就是记录过程的一张备忘录
三、 动态规划原理:动态规划同贪心法和分治法有点相似,就是得找出最优子结构,从而求得问题的最优解。讲笼统一点就是,把问题分解(分治法)成子问题,再从子问题中找出子问题的最优解,然后构成问题的最优解。其他的不多说了,多说也无益。
四 、 子问题:01背包的子问题就是一件物品对重量的影响。
此处n=4,W=7
在这里插入图片描述
五 、 例子:说那么多也无用,我认为想学习动态规划就必须得多做有关动态规划的题,因为在动态规划中,不同的定义会有不同的解法。(比如:就01背包来说,求的是最大价值,定义可以是针队不同重量,求最大价值。还有就是,针队不同价值,求最少重量)看到了把,这两种定义,具体应用得看问题的规模。(这里不详细说,想参加什么竞赛的可以了解一下)。
下面给出这两种定义的代码。
这里补充一下:不知道怎么求状态转移方程的可以先1、暴力递归——2、带自顶向下备忘录的递归——3、自底向下的动态规划。备忘录和动态规划复杂度是一样的,只是求解时顺序不一样而已。(有的书说备忘录有冗余)
(1)针队不同重量,求最大价值。(这也是很多算法书的例子)

#include <iostream>
#include <algorithm>

using namespace std;

#define MAX_N 100

int n = 4;
int W = 5;
int w[MAX_N] = { 2,1,3,2 };
int v[MAX_N] = { 3,2,4,2 };
int dp[MAX_N + 1][MAX_N + 1];//记忆化数组
void solve()
{
	for(int i = 0; i < n; i++)
		for (int j = 0; j <= W; j++)
		{
			if (j < w[i])
				dp[i + 1][j] = dp[i][j];
			else
				dp[i + 1][j] = max(dp[i][j], dp[i][j - w[i]] + v[i]);
		}
	cout << dp[n][W];
}
void main()
{
	memset(dp, 0, sizeof(dp));
	solve();
}

(2)针队不同价值求最少重量

#include<iostream>
#include<algorithm>

using namespace std;

#define MAX_N 100
#define MAX_V 10000
#define INF 999999
typedef long long ll;
int n = 4;
int w[MAX_N] = { 2,1,3,2 };
int v[MAX_N] = { 3,2,4,2 };
ll W = 5;
int dp[MAX_N + 1][MAX_V*MAX_N + 1];

void solve()
{
	fill(dp[0], dp[0] + MAX_N*MAX_V + 1, INF);//把数组所有元素设维无穷大
	dp[0][0] = 0;
	for (int i = 0; i < n; i++)
		for (int j = 0; j <= MAX_N*MAX_V; j++)//j是最大价值
		{
			if (j < v[i])
				dp[i + 1][j] = dp[i][j];
			else
				dp[i + 1][j] = min(dp[i][j], dp[i][j - v[i]] + w[i]);//针队不同价值计算最少重量
		}
	int res = 0;
	for (int j = 0; j < MAX_N*MAX_V; j++)
		if (dp[n][j] <= W) res = j;//价值
	cout << res;
}

void main()
{
	solve();
}

好了,想要了解更多,可以在评论下方留言。

猜你喜欢

转载自blog.csdn.net/weixin_44771588/article/details/102633828
今日推荐