C++實現0-1揹包問題 動態規劃 非遞歸

前兩天在華爲筆試題的時候遇到了這個問題,做完之後發現自己有欠缺,回來趕緊複習一下

本文鏈接https://blog.csdn.net/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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章