揹包問題:0-1揹包以及完全揹包的動態規劃解決

 

0-1揹包問題

問題描述n個重量分別爲{w1w2wn}的物品它們的價值分別爲{v1v2vn}給定一個容量爲W的揹包。

    設計從這些物品中選取一部分物品放入該揹包的方案每個物品要麼選中要麼不選中要求選中的物品不僅能夠放到揹包中而且重量和爲W具有最大的價值。

 

             即要確定x1x2、…、xn的值 01 ),使    w1w2wn £  W v1x1+v2x2+…+vnxn 取得最大值。

 

f[i][j],其中i代表加入揹包的是前i件物品,j表示揹包的承重,f[i][j]表示當前狀態下能放進揹包裏面的物品的最大總價值。那麼,f[n][m]就是我們的最終結果了。

(1)假如我們放進揹包,f[i][j] = f[i - 1][j - weight[i]] + value[i],這裏的f[i - 1][j - weight[i]] + value[i]應該這麼理解:在沒放這件物品之前的狀態值加上要放進去這件物品的價值。

  (2)假如我們不放進揹包,f[i][j] = f[i - 1][j]。

    因此,我們的狀態轉移方程就是:f[i][j] = max(f[i][j] = f[i - 1][j] , f[i - 1][j - weight[i]] + value[i]) 

#include "pch.h"
#include <iostream>
#include<algorithm>
#define V 500
using namespace std;
int weight[20 + 1];
int value[20 + 1];
int f[20 + 1][V + 1];
int fk[20 + 1];
static int count = 0;
void trace(int n,int m){
	if (n == 0) return;
	//f[i][j] = max(f[i - 1][j], f[i - 1][j - weight[i]] + value[i]);
	fk[n]= (f[n][m] == (f[n - 1][m - weight[n]] + value[n])?1 : 0);
	f[n][m] != (f[n - 1][m - weight[n]] + value[n]) ?  trace(n-1,m) : trace(n-1, m - weight[n]);

}
int main()
{
	
	int n, m;
	cout << "請輸入物品個數:";
	cin >> n;
	cout << "請分別輸入" << n << "個物品的重量和價值:" << endl;
	for (int i = 1; i <= n; i++) {
		cin >> weight[i] >> value[i];
	}
	cout << "請輸入揹包容量:";
	cin >> m;
	for (int i = 0; i <=n ; i++)
	{
		f[i][0] = 0;
	}
	for (int i = 0; i <= m; i++)
	{
		f[0][m] = 0;
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			if (weight[i] > j) {
				f[i][j] = f[i - 1][j];
			}
			else {
				f[i][j] = max(f[i - 1][j], f[i - 1][j - weight[i]] + value[i]);
			}
		}
	}
	trace(n, m);
	for (int i = 1; i <=n; i++)
	{
		cout << fk[i] << " ";
	}
	cout << "0/1揹包能放的最大價值爲:" << f[n][m] << endl;
}

完全揹包問題

【問題描述】n種重量和價值分別爲wivi1in)的物品從這些物品中挑選總重量不超過W的物品求出挑選物品價值總和最大的挑選方案這裏每種物品可以挑選任意多件

 



#include <iostream>
#define V 500
using namespace std;
int weight[20 + 1];
int value[20 + 1];
int f[20 + 1][V + 1];
int fk[20 + 1][V + 1];
int main() {
    int n, m;
    cout << "請輸入物品個數:";
    cin >> n;
    cout << "請分別輸入" << n << "個物品的重量和價值:" << endl; 
    for (int i = 1; i <= n; i++) {
        cin >> weight[i] >> value[i];
    }
    cout << "請輸入揹包容量:";
    cin >> m;
    for (i=1;i<=n;i++)
     for (j=1;j<=m;j++)
     {  if (j<weight[i])
           f[i][j]=f[i-1][j];
        else
           f[i][j]=max(f[i-1][j],f[i][j-weight[i]]+value[i]);
     }


    cout << "揹包能放的最大價值爲:" << f[n][m] << endl;
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章