P1120 小木棍 資料加強版 (搜尋剪枝)

2021-10-18 13:54:55 字數 1280 閱讀 3362

#include

using

namespace std;

const

int maxn =70;

const

int maxv =

3260

;int it_num =0;

int s, n, l[maxn]

;bool vis[maxn]

, s[maxn]

[maxv]

;bool

cmp(

int lhs,

int rhs)

bool

dfs(

int sum,

int val,

int num,

int pos)

if(sum == val)

return

dfs(sum,

0, num +1,

1);for

(int pf =

0; pos <= n; pos++

)else

return

true;}

return

false;}

intmain()

n = cnt;

sort

(l +

1, l + cnt +

1, cmp)

;//cout << s << endl;

for(

int i = mlen; i <= s; i++)}

//cout << it_num << endl;

return0;

}/*一開始指望利用map優化,但是回溯的地方無法利用有限記憶體來儲存狀態,所以不行

還有乙個難想卻特別特別重要的優化:如果當前長棍剩餘的未拼長度等於當前木棍的長度或原始長度,繼續拼下去時卻失敗了,就直接回溯並改之前拼的木棍。有些人不太明白這個優化,這裡簡單說一下:

當前長棍剩餘的未拼長度等於當前木棍的長度時,這根木棍在最優情況下顯然是拼到這(如果用更多短木根拼完剩下的這段,把這根木棍留到後面顯然不如把更多總長相等的短木棍扔到後面)。如果在最優情況下繼續拼下去失敗了,那肯定是之前的木棍用錯了,回溯改即可。\color\text(update at 2019.7.24)

當前長棍剩餘的未拼長度等於原始長度時,說明這根原來的長棍還一點沒拼,現在正在放入一根木棍。很明顯,這根木棍還沒有跟其它棍子拼接,如果現在拼下去能成功話,它肯定是能用上的,即自組或與其它還沒用的木棍拼接。但繼續拼下去卻失敗,說明現在這根木棍不能用上,無法完成拼接,所以回溯改之前的木棍。

*/

P1120 小木棍 資料加強版

喬治有一些同樣長的小木棍,他把這些木棍隨意砍成幾段,直到每段的長都不超過 50 現在,他想把小木棍拼接成原來的樣子,但是卻忘記了自己開始時有多少根木棍和它們的長度。給出每段小木棍的長度,程式設計幫他找出原始木棍的最小可能長度。首先在讀入的時候忽略掉長度大於50的木棍 最重要 順便還要記錄一下最短的木...

P1120 小木棍 資料加強版

原題鏈結 不得不說,這題真的是一道深度搜尋毒瘤題qwq,整整坑了我乙個上午。先說一下大體思路 1.讀入資料的同時 注意過濾掉長度大於50的木棍 算出所有小木棍的總和sum,因為至少所有的小木棍會拼成一根長度為sum的超大木棍 2.找出所有小木棍中長度最大的那根max,原始長度len一定大於等於這個m...

P1120 小木棍 資料加強版

一道不錯的剪枝題,用到的剪枝優化比較多,剪枝思路也值得學習 在這裡我只採取了能通過此題的剪枝,似乎還可以繼續優化?剪枝講解在注釋裡 include include include include includeusing namespace std const int maxn 70 inline ...