揹包問題(1) 0/1揹包、完全揹包

0/1揹包問題

假設有n件物品,他們的體積分別爲v[i],價值分別爲w[i],有一個容量爲m的揹包,如何選擇物品裝入揹包能夠的得到最大的價值。(物品種類不超過N個)

  • 條件:每件物品至多隻能選擇1次
  • 狀態定義:f [ i ],表示揹包體積爲 i 時的最大價值
  • 轉移方程:f [ i ] = max( f [i] , f [ i - v [ i ] ] + w [ i ] )
#include<iostream>
#include<algorithm>

using namespace std;

int main()
{
	//N的值根據題意設定
	const int N = 1000;
	int f[N], v[N], w[N], n ,m;
	cin >> n >> m;
	//循環輸入物品的體積和價值
	for(int i=0; i<=n; i ++)	
		cin >> v[i] >> w[i] ;
	//對於每件物品
	for(int i=1; i<=n; i++)
		//因爲要使用上一次計算的某個體積時的最大價值,所以從大到小遍歷,對於任何可能存在的體積情況,最大價值可能爲
		//1.上一次計算該體積時的最大價值
		//2.上一次計算該體積 - v[i](剛好可以容納當前物品體積)時的最大價值加上當前物品的價值
		for(int j=m; j>=v[i]; j--)
			f[j] = max( f[j] , f[j - v[i]] + w[i] );
	//不用循環遍歷最後一步得到的f數組
	//1.因爲第二層尋循環每次都從f[m]開始,所以f[m]必存在
	//2.如果物品體積全部大於m,則f[m]=0
	//3.每次循環對於f[m]來說,都會找到可以加入物品i的合適體積,也就是說這個體積首先可以裝入物品i,其次還有
	//最大的剩餘體積,這些最大的剩餘體積的最大價值計算在循環的其他部分完成,並根據計算結果更新最大價值
	cout << f[m];
	return 0;
}	

完全揹包問題

假設有n件物品,他們的體積分別爲v[i],價值分別爲w[i],有一個容量爲m的揹包,如何選擇物品裝入揹包能夠的得到最大的價值。(物品種類不超過N個)

  • 條件:每件物品至多能選擇無數次
  • 狀態定義:f [ i ],表示揹包體積爲 i 時的最大價值
  • 轉移方程:f [ i ] = max( f [i] , f [ i - v [ i ] ] + w [ i ] )
#include<iostream>
#include<algorithm>

using namespace std;

int main()
{
	//N的值根據題意設定
	const int N = 1000;
	int f[N], v[N], w[N], n ,m;
	cin >> n >> m;
	for(int i=0; i<=n; i ++)	
		cin >> v[i] >> w[i] ;
	for(int i=1; i<=n; i++)
		//一個物品可以使用無數次,所以可以使用本次循環計算得到的小體積時的最大價值,從小到大遍歷,對於任何可能存在的體積情況,最大價值可能爲
		//1.上一次計算該體積時的最大價值
		//2.上一次計算該體積 - v[i](剛好可以容納當前物品體積)時的最大價值加上當前物品的價值
		for(int j=v[i]; j<=m; j++)
			f[j] = max( f[j] , f[j - v[i]] + w[i] );
	cout << f[m];
	return 0;
}	
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章