演算法課 五種蠻力法解決01揹包問題

2021-10-05 15:56:39 字數 3902 閱讀 8098

答案0/1揹包問題【演算法中非常經典的乙個例題,多種不同的演算法可以來實現】

有n個重量分別是w1,w2…,wn的物品(物品編號為1-n)

它們的價值分別為v1,v2,…,vn

給定乙個容量為w的揹包。設計從這些物品中選取一部分放入該揹包的方案。

每個物品要麼選中要麼不選中【每種物品是唯一的】,

要求選中的物品不僅能夠放在揹包中【能放得下】,而且具有最大的價值。

並對如下所展示的5個物品求出w=10時的最佳解。

物品編號 重量 價值

1 2 6

2 2 3

3 6 5

4 5 4

5 4 6

分析:並對如的5個物品求出w不超過10時的最佳解。

我們設定有五個物品

五個物品一開始都不選

用string表示為 00000

用j來控制狀態選擇

1我們可以利用窮舉寫出5個變數的全排列

而5個變數分別可以代表的當前狀態下的當前位子的選擇

於是我們建立新的字串,全排列的中的狀態賦值即可,這樣我們就得到了所有可能的選擇狀態。

然後更新maxv和str即可

2用二進位制列舉

形如1000001

11110001

1表示選擇,0表示未選擇的方式

可參考我寫的得到整數x

方法一:字串蠻力

#include

#include

#include

using

namespace std;

intmain()

, v[5]

=;string pres =

"00000"

;int ww =

0, vv =

0, maxv =0;

string str;

char s[

1000];

for(

int j =

0; j <

5; j++

)for

(int a =

0; a <

5; a++

)for

(int b =

0; b <

5; b++

)for

(int c =

0; c <

5; c++

)for

(int d =

0; d <

5; d++

)for

(int e =

0; e <

5; e++

)for

(int i =

0; i <

5; i++

)cout << str[i]

; cout << endl;

cout << maxv << endl;

return0;

}

方法二:二進位制列舉
#include

using

namespace std;

int ww,vv,maxv,strres;

intmain()

, v[5]

=;for(

int i=

0;i<

1<<

5;i++

)//二進位制最大可能選擇數

for(

int i=

0;i<

5;i++

)cout<<

(strres>>i&1)

;//因為是選擇情況,所以直接輸出

cout

return0;

}

方法三:dfs

無法儲存最大路徑

#include

using

namespace std;

int ww,vv,maxv,strres;

int w =10;

int w[5]

=, v[5]

=;int str[5]

;int ans[5]

;void

dfs(

int tw,

int ans)

for(

int i=

0;i<

5;i++)if

(!str[i]

&&tw>=w[i])}

intmain()

三.2閆老闆思考角度
#include

using

namespace std;

int w[5]

=, v[5]

=;int x[5]

;int maxv =0;

int ans[5]

;void

dfs(

int i,

int ww,

int vv)

//記錄最優狀態

else

return

;//這裡給他加了個退出

x[i]=1

;dfs

(i +

1, ww + w[i]

, vv + v[i]);

x[i]=0

;dfs

(i +

1, ww, vv);}

intmain()

方法四:全排列

利用next_permuatation的特性,全排列,而我們只需要擷取前面五位的狀態即可

#include

#include

#include

using

namespace std;

intmain()

, v[5]

=;string s =

"0000011111"

;int ww =

0, vv =

0, maxv =0;

string str;

for(

int j =

0; j < n; j++

)while

(next_permutation

(s.begin()

,s.end()

));}

for(

int i=

0;i<

5;i++

)cout << str[i]

; cout

return0;

}

方法五:陣列蠻力

利用陣列表示01

#include

#include

#include

using

namespace std;

int s[5]

;int

main()

, v[5]

=;int ww =

0, vv =

0, maxv =0;

string str;

for(s[0]

=0; s[0]

<

2; s[0]

++)for(s[1]

=0; s[1]

<

2; s[1]

++)for(s[2]

=0; s[2]

<

2; s[2]

++)for(s[3]

=0; s[3]

<

2; s[3]

++)for(s[4]

=0; s[4]

<

2; s[4]

++)cout << maxv << endl;

getchar()

;getchar()

;return0;

}

11001

15

蠻力法解決0 1揹包問題

使用蠻力法解決0 1揹包問題,就是將所有的物品裝入揹包的可能全部列舉出來。這個可以通過遞迴的方式實現。遞迴的過程可以看成是對一棵樹的深度優先遍歷 例如上圖,假設從揹包中的1號物品開始列舉所有的可能。如果每一層僅僅簡單的在迴圈中使用遞迴,則該程式就不會結束。需要使用乙個一維向量用於標記當前哪些編號已經...

0 1揹包問題(蠻力法)

用蠻力法解決0 1揹包問題 例子輸入 4 6 5 43 4 2 31 1輸出 10 6 8 include include using namespace std intmain int w 5 v 5 int max 0 每輪最大價值 int max1 0 最終最大價值 int weight 0 ...

演算法分析與設計 蠻力法0 1揹包

蠻力法是一種簡單直接解決問題的方法,常常直接基於問題的描述,所以蠻力法也是最容易應用的方法。蠻力法所依賴 的基本技術是遍歷,即採用一定的策略依次處理待求解問題的所有元素,從而找出問題的解。由於其需要依次窮舉待處理的元素,因此蠻力法是一種典型的指數級時間演算法。給定n個重量為 價值為的物品和乙個容量為...