IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 动态规划-01背包问题通俗详解 -> 正文阅读

[数据结构与算法]动态规划-01背包问题通俗详解

如题所示:

01背包问题


时间限制: 1000 ms ??? ??? 内存限制: 65536 KB
【题目描述】

一个旅行者有一个最多能装?MM?公斤的背包,现在有?nn?件物品,它们的重量分别是W1,W2,...,WnW1,W2,...,Wn,它们的价值分别为C1,C2,...,CnC1,C2,...,Cn,求旅行者能获得最大总价值。

【输入】

第一行:两个整数,MM(背包容量,M<=200M<=200)和NN(物品数量,N<=30N<=30);

第2..N+12..N+1行:每行二个整数Wi,CiWi,Ci,表示每个物品的重量和价值。

【输出】

仅一行,一个数,表示最大总价值。

核心思路:

定义vs为背包容量,n为物品数量

定义数组w[i]表示第i个物品的重量(费用)

定义数组v[i]表示第i个物品的价值

定义数组dp[i][j]表示前i个物品的在不超过重量j的情况下的最大价值

如下:

int v[1000],w[1000];
int dp[1000][1000];
int vs,n;

那么首先dp[0][1~j]都初始化为0

for(int i=1;i<=vs;i++){
    	dp[0][i]=0;
	}

这个知道吧,前0个物品不论背包能装多少价值都为0,这是初始状态,为后面也有用

 for(int i=1;i<=n;i++)
    {
    	for(int j=vs;v>0;v--)
    	{
    		if(w[i]<=j)
    		    dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
    		else
    		    dp[i][j]=dp[i-1][j];
		}
	}

直接上代码,我也不叨叨那些状态转移方程,把这些代码吃透了就行了

给一个例子 假如说

输入背包容量为10,有3个物品

第一个物品 重量6? ?价值5

第二个物品 重量8? ?价值2

第三个物品?重量2? 价值4

在初始化dp[0][1~j]为0后,进入上行代码

w[1]=第一个物品重量=6

在j>=6时 dp[1][j-w[1]]都等于物品1的价值 这里dp[i-1][j]就上上文的初始化起了作用,为0嘛,能够比较 因为装进去了就要从背包里扣除他的重量

在j<=6时,第一个物品装不进去,所以前1个物品装入背包的价值等于前i-1个物品的价值,因为你什么也没装,之前装在里面的还保持着它的价值,重量,这里前i-1为0,说明背包空了

第二个循环?

w[2]=第二个物品重量=8

在j>=8时 比较是否装进去 这里第一个物品的价值大于第二个物品的价值,严谨的说前i-1个物品的价值大于第i个物品装进去后的价值

j<=8时 和上文一样,背包保持原样,装不进去

第三个循环

同上

最终答案锁定在dp[n][vs]上为9

这里要说明初始化可有可无

完整代码如下:

#include<iostream>
#include<cmath>
using namespace std;

int v[1000],w[1000];
int dp[1000][1000];
int vs,n;
int main()
{

	
	cin>>vs>>n;
	for(int i=1;i<=n;i++)
    {
    	cin>>w[i]>>v[i];
    }
    for(int i=1;i<=vs;i++){
    	dp[0][i]=0;
	}
    for(int i=1;i<=n;i++)
    {
    	for(int j=vs;j>0;j--)
    	{
    		if(w[i]<=j)
    		    dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
    		else
    		    dp[i][j]=dp[i-1][j];
		}
	}
	cout<<dp[n][vs];
	return 0;
}

相对于暴力穷举,动态规划的优点在于能够利用数组记忆之前已计算出的子最优解,避免了重复计算,提高了效率,此题还有优化空间的方法,请参阅其他资料

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-29 09:37:13  更:2021-08-29 09:37:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:54:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码