答案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個重量為 價值為的物品和乙個容量為...