DFS學習心得 0 1揹包 DFS常見題目型別

2021-10-02 07:26:40 字數 4299 閱讀 6830

有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的物品不放入揹包時 搜尋...