有n件物品,每件物品的重量為w[i],價值為c[i]。現在需要選出若干件物品放入乙個容量為v的揹包中,使得在選入揹包的物品重量和不超過容量v的前提下,讓揹包中物品的價值之和最大,求最大價值(1<=n<=20)
sample input:
5 8 //5件物品,揹包容量為8
3 5 1 2 2 //重量
4 5 2 1 3 //價值
sample output:
10
參考**
#include
const
int maxn =30;
int w[maxn]
,c[maxn]
;int n, v, maxvalue;
void
dfs(
int index,
int sumw,
int sumc)
return;}
//岔道口
dfs(index +
1, sumw, sumc)
;//不選index這個物件
dfs(index +
1, sumw + w[index]
, sumc + c[index]);
//選擇index物件
}int
main
(int argc,
char
const
*ar**)
for(
int i =
0; i != n;
++i)
dfs(0,
0,0)
;//初始為零物件,當前總質量和總價值為0
printf
("%d\n"
, maxvalue)
;return0;
}
優化:剪枝(通過題目條件的限制節省dfs計算量)
優化後的**
#include
const
int maxn =30;
int w[maxn]
,c[maxn]
;int n, v, maxvalue;
void
dfs(
int index,
int sumw,
int sumc)
}int
main
(int argc,
char
const
*ar**)
for(
int i =
0; i != n;
++i)
dfs(0,
0,0)
;//初始為零物件,當前總質量和總價值為0
printf
("%d\n"
, maxvalue)
;return0;
}
常見dfs問題
題目描述:
給定n個整數(可能有負數),從中選擇k個數(這k個數不重複),使得這k個數之和恰好等於乙個給定的整數x;如果有多種方案,選擇它們中元素平方和最大的乙個。資料保證這樣的方案唯一。
sample input:
4 2 6 //4個整數 選2個 使得之和為6
2 3 3 4 //4個整數
sample output:
2 4 //平方和最大的乙個
#include
#include
using std::vector;
const
int maxn =
100010
;vector<
int>ans, temp;
//分別存放最大方案和臨時方案
int n, k, x, maxsumsqu =-1
;//分別存放總數n,選擇的個數k,等於的值x,最大平方數maxsumsqu
int a[maxn]
;//輸入的資料
void
dfs(
int index,
int nowok,
int sum,
int sumsqu)
return;}
//分別表示:已處理完n個數,超過k的個數,超過x
if(index == n|| nowok > k || sum > x)
return
;//選index號整數
temp.
push_back
(a[index]);
//不可以重複選擇
dfs(index +
1, nowok +
1, sum + a[index]
, sumsqu + a[index]
* a[index]);
//可以重複選擇index號整數
//dfs(index , nowok + 1, sum + a[index], sumsqu + a[index] * a[index]);
//不選index號整數
temp.
pop_back()
;dfs
(index +
1, nowok, sum, sumsqu);}
intmain
(int argc,
char
const
*ar**)
dfs(0,
0,0,
0);for
(vector<
int>
::const_iterator it = ans.
begin()
; it != ans.
end();
++it)
printf
("\n");
return0;
}
題目變式:
假設n個整數的每乙個都可以被選擇多次,那麼選擇k個數,使得k的數值和恰好為x。
sample input:
3 5 17 //3個整數 選5個 使得之和為17
1 4 7 //3個整數
sample output:
2 4 //平方和最大的乙個
#include
#include
using std::vector;
const
int maxn =
100010
;vector<
int>ans, temp;
//分別存放最大方案和臨時方案
int n, k, x, maxsumsqu =-1
;//分別存放總數n,選擇的個數k,等於的值x,最大平方數maxsumsqu
int a[maxn]
;//輸入的資料
void
dfs(
int index,
int nowok,
int sum,
int sumsqu)
return;}
//分別表示:已處理完n個數,超過k的個數,超過x
if(index == n|| nowok > k || sum > x)
return
;//選index號整數
temp.
push_back
(a[index]);
//不可以重複選擇
//dfs(index + 1, nowok + 1, sum + a[index], sumsqu + a[index] * a[index]);
//可以重複選擇index號整數
dfs(index , nowok +
1, sum + a[index]
, sumsqu + a[index]
* a[index]);
//不選index號整數
temp.
pop_back()
;dfs
(index +
1, nowok, sum, sumsqu);}
intmain
(int argc,
char
const
*ar**)
dfs(0,
0,0,
0);for
(vector<
int>
::const_iterator it = ans.
begin()
; it != ans.
end();
++it)
printf
("\n");
return0;
}
DFS解決01揹包問題
本篇博文著重用dfs解決著名的揹包問題 01揹包問題要點在 選與不選。所以我們很容易聯想到dfs來解決這個問題!下面我們來看看是如何實現的 includeusing namespace std const int n 30 int w n value n n,maxvalue 0,v void df...
DFS 剪枝解決0 1揹包
有num件物品,每件物品的重量為w i 價值為v i 現在需要選出若干件物品放入乙個容量為capacity的揹包中,使得在選入揹包的物品重量和不超過容量capacity的前提下,讓揹包中的物品的價值之和最大,求最大價值 1 num 20 分析 可用dfs搜尋所有情況,但缺點在於進行過多無用搜尋。可以...
DFS解01揹包問題
01揹包問題的dfs解法 直接dfs未剪枝 時間複雜度 o 2n nn 其原因是對任意的物品,都是選或者不選 兩次的情況 dfs三個形參 物品序號index,放進揹包的重量sumw,以及放進揹包的總價值sumc 主要搜尋路徑 序號為index的物品放入揹包時 序號為index的物品不放入揹包時 搜尋...