AcWing 167 木棒(dfs 剪枝)

2022-07-25 16:27:21 字數 1673 閱讀 1829

喬治拿來一組等長的木棒,將它們隨機地砍斷,使得每一節木棍的長度都不超過50個長度單位。

然後他又想把這些木棍恢復到為裁截前的狀態,但忘記了初始時有多少木棒以及木棒的初始長度。

請你設計乙個程式,幫助喬治計算木棒的可能最小長度。

每一節木棍的長度都用大於零的整數表示。

注意: 資料中可能包含長度大於50的木棒,請在處理時忽略這些木棒。

輸入格式

輸入包含多組資料,每組資料報括兩行。

第一行是乙個不超過64的整數,表示砍斷之後共有多少節木棍。

第二行是截斷以後,所得到的各節木棍的長度。

在最後一組資料之後,是乙個零。

輸出格式

為每組資料,分別輸出原始木棒的可能最小長度,每組資料佔一行。

輸入樣例:

9

5 2 1 5 2 1 5 2 1

41 2 3 4

0

輸出樣例:
6

5

演算法:dfs + 剪枝

題解:剪枝:1、優先搜尋順序(從大大小),優先嘗試較長的木棒。

2、要求先後加入的木棒有單調性,因為你每根木棒都要用,之前加入和之後加入都是乙個樣。

3、當拼接乙個新木棒時,我加入乙個木棒,失敗了,說明,之後用到這個木棒拼接乙個新木棒的時候都會失敗。

4、當我現在我要加入的木棒拼接上去,正好等於拼接的長度,但是拼接失敗了,說明之後繼續拼接下去也是失敗。

#include #include 

#include

using

namespace

std;

const

int maxn = 1e5+7

;int

arr[maxn];

intvis[maxn];

intk, cnt;

bool cmp(int a, int

b) bool dfs(int stick, int cal, int last, int

len)

if(cal == len)

int fail = 0; //

剪枝2,記錄重複值

for(int i = last; i < k; i++)

vis[i] = 0

; fail =arr[i];

if(cal == 0 || cal + arr[i] == len) }}

return

false; //

當所有分支都嘗試過,並且還沒成功

}int

main()

sum +=x;

max_len =max(max_len, x);

arr[k++] =x;

}sort(arr, arr + k, cmp); //

剪枝1int

i;

for(i = max_len; i <= sum; i++)

cnt = sum / i; //

獲取木棒的數量

for(int j = 0; j < k; j++)

if(dfs(1, 0, 0

, i))

}printf(

"%d\n

", i);

}return0;

}

AcWing 167 木棒(搜尋)

深度搜尋 剪枝 原題鏈結 題目思路 從常用剪枝技巧開始 證明 2 反證法,若後面還有機會完整拼完,那麼一定會用到這一截木棍 第一截 矛盾。證明 3 反證法,若此處不用當前小截木棍,而換成其他截木棍組成等長的,再補上。那麼這截放到後面可以完整拼成的話,是矛盾的,因為這截與剛才 組成截 等價,而剛才是拼...

acwing167 深度搜尋 剪枝 木棒

喬治拿來一組等長的木棒,將它們隨機地砍斷,使得每一節木棍的長度都不超過50個長度單位。然後他又想把這些木棍恢復到為裁截前的狀態,但忘記了初始時有多少木棒以及木棒的初始長度。請你設計乙個程式,幫助喬治計算木棒的可能最小長度。每一節木棍的長度都用大於零的整數表示。輸入包含多組資料,每組資料報括兩行。第一...

167 兩數之和II (Two SumII)

暴力法兩次雜湊表 一次雜湊表 和1.兩數之和 leetcode 1.兩數之和 csdn不同之處在於,本題附加了有序的特殊限定。同樣可以借助於暴力法在時間複雜度o n 2 o left n right o n2 和空間o 1 o 1 o 1 解決。和雜湊表時間o n o left n right o ...