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

2021-09-10 07:28:22 字數 2535 閱讀 8986

原題:

題意:

有n(<=65)根小木棍,長度a

ia_i

ai​(<=50),這些小木棍是由x根l長木棍切割而得,現在x和l不確定,讓你求最小的l。

題目說了如果出現大於50的木棍要忽略。

解析:

首先當然是要列舉長度l了,下界為給出長度最大值mama

ma,上界為所有木棍長度和sum

sumsu

m。當然sum

sumsu

m是一定成立的,所以列舉到sum

/2

sum/2

sum/

2即可。

開始的時候,我有點犯傻了,以為只要資料可以組合,貪心組合即可,用鍊錶存狀態的更新情況,用陣列維護剩餘的棍子,一發牛b哄哄的**wa了。

#include

using namespace std;

#define debug(i) printf(" # %d\n",i)

int a[66]

, sum, ma;

bool vis[

3255];

struct state e[

3255];

int sta[

3255

], co;

void

erase

(int s,

int&n,

int len)

int j =0;

for(

int i =

1; i <= n; i++

) s[

++j]

= s[i];}

n = j;

}bool cmp

(int a,

int b)

intmain()

a[i]

= tmp;

sum +

= tmp;

ma =

max(ma, tmp);}

sort

(a +

1, a +

1+ n, cmp)

;int ans = sum;

for(

int len = ma; len <= sum /

2; len++)}

if(succ)

break;}

if(!succ)}if

(!cant)

}printf

("%d\n"

, ans)

;}

後來猛地想起來,選取策略是有影響的,比如用333

31111

3 \,3\, 3\, 3\, 1 1 1 1

333311

11來拼4個4,如果先選1111,那麼就不能拼了。

所以只能暴搜了,dfs(int len, int needlen, int neednum, int up)表示設定原長度為len,當前棍子還需要拼needlen,除了當前棍子還需要拼neednum根,下乙個選取來湊的棍子從up開始往下。

說說需要注意的事:

用桶來裝會比較方便,用a[len]--就可以維護剩餘木棍。

從大的木棍的開始選,因為前面一堆小的堆起來,搜尋失敗後回溯的過程會非常龐大。

因為這題只需要輸出乙個答案即可,而且我們對原長度從小到大判斷,所以只要遇到乙個可以的一定是最優解,那麼我們輸出後ext(0)結束程式就不用回溯了。

在dfs中列舉下乙個選擇的木棍時,從大到下,大的那邊應該從up和needlen的小值開始,小的那邊到所有木棍的最小值結束。

重要點:如果剛開始選擇木棍,即needlen==len,那麼選完後就return,因為這個木棍一定會被選。即第乙個選什麼並不重要。

重要點:如果選擇的木棍長度和需要的長度相同,還不行,那就return。因為兩個1一定比乙個2用起來靈活。

#include

using namespace std;

int a[

100]

, n;

int ma, mi, sum;

void

dfs(

int len,

int needlen,

int neednum,

int up)

if(needlen ==0)

for(

int i =

min(up, needlen)

; i >= mi; i--)}

}int

main()

int ans = sum;

for(

int i = ma; i <= sum /

2; i++

)printf

("%d\n"

, ans)

;}

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 ...