揹包問題

問題描述
有n個物品和一個大小爲m的揹包. 給定一個數組A表示每個物品的大小, 一個數組V表示每個物品的價值.
那麼最多能裝入揹包的總價值爲多大?

用F(i, j)表示前 i 個物品放入大小爲 j 的揹包中所獲得的最大價值

這樣的話, 其實每當我們看到第i個商品的時候, 我們都有兩種選擇, 就是放進揹包或者是不放進揹包.
首先, 如果第 i 個物品的大小大於揹包的容量, 那麼這個物品不能放進揹包, 也就是說, 此時這所有的 i 個商品放入大小爲 j 的揹包中的最大價值爲 F(i - 1, j)
因爲第 i 個商品無法放入揹包中.
其次, 如果第 i 個物品的大小小於揹包的容量, 那麼我們要考慮的就是, 放進去能得到最大價值還是不放
如果我們選擇放第 i 個商品, 那麼我們要保證揹包的空間足以容納這個商品, 也就是說此時的 F(i, j) = F(i - 1, j - A[i]) + V[i];
如果不放第 i 個商品, F(i, j) = F(i - 1, j)

class Solution {
public:

	int backPackII(int m, vector<int> &A, vector<int> &V) {
		// write your code here
		int col = m + 1;
		int row = V.size() + 1;

		vector<vector<int>> v(row);
		for (auto & e : v)
		{
			e.resize(col, 0);	//初始化, 保證第一行第一列全爲 0
		}

		for (int i = 1; i < row; ++i)
		{
			for (int j = 1; j < col; ++j)
			{
				if (A[i - 1] > j)
				{
					v[i][j] = v[i - 1][j];	//第 i 個商品的大小大於此時揹包的大小
				}
				else
				{
					//考慮第 i 個商品放和不放兩種情況中的最大價值
					v[i][j] = max(v[i - 1][j], v[i - 1][j - A[i - 1]] + V[i - 1]);//注意第 i 個商品在給定數組中的索引是 i - 1
				}
			}
		}
		return v[row - 1][col - 1];
	}
};

上述方法看做二維數組的話, 其實我們在修改二維數組第 i 行的數值時, 每一次只用到了 i - 1行的數值, 也就是說其實我們可以利用一維數組完成這個問題.

class Solution {
public:
	int backPackII(int m, vector<int> &A, vector<int> &V) {
		// write your code here
		int n = m + 1;
		int len = A.size();

		vector<int> v(n, 0);

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

				}
			}
		}
		return v[n - 1];
	}
};
發佈了239 篇原創文章 · 獲贊 31 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章