洛谷P1120 小木棍 資料加強版

2021-10-18 07:26:59 字數 1713 閱讀 7618

喬治有一些同樣長的小木棍,他把這些木棍隨意砍成幾段,直到每段的長都不超過50。

現在,他想把小木棍拼接成原來的樣子,但是卻忘記了自己開始時有多少根木棍和它們的長度。

給出每段小木棍的長度,程式設計幫他找出原始木棍的最小可能長度。

共二行。

第一行為乙個單獨的整數n表示砍過以後的小木棍的總數,其中n≤65

(管理員注:要把超過50的長度自覺過濾掉,坑了很多人了!)

第二行為n個用空個隔開的正整數,表示n根小木棍的長度。

乙個數,表示要求的原始木棍的最小可能長度輸入9

5 2 1 5 2 1 5 2 1輸出6

一道比較複雜的題目(主要難度在於對**進行剪枝),先輸入所有木棍的長度,從其中最大的開始搜尋,判斷以當前長度是否所有木棍能拼接成,如果可以就輸出當前長度,退出迴圈。

#include

using namespace std;

int n,a[70]

,c[70

],m;

int sum=

0,maxmum=

0,len;

bool flag,b[70]

;//陣列b用來表示該位置的小木棍有沒有被使用組合原始木棍。

void

dfs(

int t,

int last,

int rest)

int k=n;

for(

int i=

1; i<=n; i++)}

b[k]=1

;//標記

dfs(t+

1,k+

1,len-a[k]);

//下乙個情況

b[k]=0

;//回溯

return;}

int l=last,r=n,mid;

while

(l//使用二分,找到第一根長度小於等於原始木棍長度的木棍

/*如果當前長棍剩餘的未拼長度等於當前木棍的長度或原始長度,繼續拼下去時卻失敗了,就直接回溯之前拼的木棍。*/

for(

int i=l; i<=n; i++

) i=c[i]

; i--;}

}}intmain()

a[++n]

=x; sum+

=a[n]

;//統計所有成功輸入的木棍的長度和

if(maxmumsort

(a+1

,a+n+

1,greater<

int>()

);//便於下乙個優化

for(

int i=

1; i<=n; i++

) c[j]

=k;}

else

}for

(len=maxmum;len<=sum/

2;len++

) m=sum/len;

//計算得到一共可以組成多少根原始木棍

memset

(b,false,

sizeof

(b))

;dfs(1

,1,len);}

if(!flag)

/*如果上一步的搜尋都沒有得到正確的輸出,那麼就輸出所有木棍的長度和,即所有木根合在一起拼接成一根木棍。*/

return0;

}

洛谷 P1120 小木棍 資料加強版

題目 小木棍 思路 搜尋 剪枝。外層迭代加深,列舉最小長度,用dfs判斷。dfs維護3個變數x,y,lst,即用了x根木棍,當前拼到了y,上一根木棍的長度為lst。然後列舉拼接的木棍就好。剪枝一 從大到小排序。剪枝二 如果y不為0,那麼列舉的木棍長不要大於lst,不然就會重複搜尋。剪枝三 如果y 0...

洛谷 P1120 小木棍 資料加強版

喬治有一些同樣長的小木棍,他把這些木棍隨意砍成幾段,直到每段的長都不超過5050。現在,他想把小木棍拼接成原來的樣子,但是卻忘記了自己開始時有多少根木棍和它們的長度。給出每段小木棍的長度,程式設計幫他找出原始木棍的最小可能長度。搜尋加剪枝 剪枝 1 使用桶排,因為長度不超過50。2 列舉的長度應該能...

洛谷p1120小木棍 資料加強版 c

dfs剪枝 主要難點在於如何進行dfs的剪枝,典型例題如小木棍 洛谷p1120小木棍 可以二分答案 不二分也不會超時,我的 沒有二分 dfs看看這個答案可不可行 雖然資料很小,直接dfs也是會超時的,所以需要加入一些剪枝。1.從max 最大木棍長度,總木棍長度 要分的段數 為左面,所有木棍長度為右面...