C++实现0-1背包问题 动态规划 非递归

本文通过C++实现0-1背包问题的动态规划非递归解决方案。作者在华为笔试后进行复习,并提供详细注释的代码,帮助读者理解核心思路。此外,还推荐了相关资源辅助学习动态规划和C++向量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前两天在华为笔试题的时候遇到了这个问题,做完之后发现自己有欠缺,回来赶紧复习一下

本文链接https://blog.youkuaiyun.com/qq_34175893/article/details/79832210

不说太多了,直接把代码贴出来,任何繁琐的理论都不如代码看着直接,我在代码中进行了详细的注释,保证只要看懂并理解了关键的几句代码及注释,0-1背包问题就变得很简单,原理什么的网上的博客很多,给大家分享几个比较好的参考链接

C++向量学习

0-1背包

//#include "stdafx.h"  
// stdafx.h中没有函数库,只是定义了一些环境参数,使得编译出来的程序能在32位的操作系统环境下运行。还有其他作用,自行参考百度百科
#include <iostream>  
#include <string>
#include <vector>  

using namespace::std;

/*
0-1 背包问题(迭代版)
输入:
products_count:商品的数量
capacity:背包的容量
weight_array:商品重量数组
value_array:商品价格数组
result:结果数组
输出:
result[products_count][capacity] : 最大价值
*/
void knapsack(int products_count, int capacity, vector<int>& weight_array, vector<int>& value_array, vector<vector<int>>& result)
{
	for (int i = 1; i <= products_count; ++i)
	{
		for (int j = 1; j <= capacity; ++j)
		{
			if (weight_array[i] > j) // 当前背包的容量 j 放不下第 i 件商品时  
			{
				result[i][j] = result[i - 1][j]; // 放弃第 i 件商品,拿第 i - 1 件商品  
			}
			else
			{
				// 装入第 i - 1件商品,则容量变为j - weight_array[i]],价值加上value_array[i]
				int value1 = result[i - 1][j - weight_array[i]] + value_array[i]; 
				// 不装入第 i - 1 件商品 ,则此时容量i的价值和容量i-1的价值相同且装入的物品相同
				int value2 = result[i - 1][j];
				/**
				*  问题的核心:状态转移方程, 选出两种选择(是否装入第i件物品)中价值较大的
				*/
				result[i][j] = value1 > value2 ? value1 : value2; 
			}
		}
	}
}

int main()
{

	while (1)
	{
		/*
		vector<int> a;                                //声明一个int型向量a
		vector<int> a(10);                            //声明一个初始大小为10的向量
		vector<int> a(10, 1);                         //声明一个初始大小为10且初始值都为1的向量
		vector<int> b(a);                             //声明并用向量a初始化向量b
		vector<int> b(a.begin(), a.begin() + 3);        //将a向量中从第0个到第2个(共3个)作为向量b的初始值

		//除此之外, 还可以直接使用数组来初始化向量:

		int n[] = { 1, 2, 3, 4, 5 };
		vector<int> a(n, n + 5);              //将数组n的前5个元素作为向量a的初值
		vector<int> a(&n[1], &n[4]);        //将n[1] - n[4]范围内的元素作为向量a的初值

		//全部输出
		vector<int>::iterator t ;
		for(t=a.begin(); t!=a.end(); t++)
		cout<<*t<<" " ;

		*/
		int products_count, capacity;
		vector<int> weight_array(1, 0); //声明一个初始大小为1且初始值都为0的向量  //大小和初值都是可选参数
		vector<int> value_array(1, 0);
		cout << endl << "-----------------------------" << endl;
		cout << "please input products count and knapsack's capacity: " << endl; // 输入商品数量和背包容量  
		cin >> products_count >> capacity;
		cout << "please input weight array for " << products_count << " products" << endl;
		for (int i = 1; i <= products_count; ++i) // 循环输入每件商品的重量  
		{
			int tmp;
			cin >> tmp;
			weight_array.push_back(tmp);
		}
		cout << "please input value array for " << products_count << " products" << endl;
		for (int i = 1; i <= products_count; ++i) // 循环输入每件商品的价格  
		{
			int tmp;
			cin >> tmp;
			value_array.push_back(tmp);
		}
		vector<vector<int>> result(products_count + 1, vector<int>(capacity + 1, 0)); // 结果数组   二维 (products_count+1)*(capacity+1)
		knapsack(products_count, capacity, weight_array, value_array, result); // 调用动态规划算法  
		cout << "knapsack result is " << result[products_count][capacity] << endl;
		// 调用动态规划算法之后,在result矩阵的r=products_count,c=capacity位置上的元素的值必是最大值
		// 也就是说在任意一个products_count和capacity对应位置上的值都是当前情况下的最大价值
	}

	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值