喬治有一些同樣長的小木棍,他把這些木棍隨意砍成幾段,直到每段的長都不超過 50 。現在,他想把小木棍拼接成原來的樣子,但是卻忘記了自己開始時有多少根木棍和它們的長度。給出每段小木棍的長度,程式設計幫他找出原始木棍的最小可能長度。
首先在讀入的時候忽略掉長度大於50的木棍(最重要),順便還要記錄一下最短的木棍和最長的木棍的長度(為之後的運算剪枝),然後按照木棍的長度做一次排序(因為木棍長度都小於等於50,本人用的是桶排序),接著就可以開始搜尋了。
1、從最長的木棍的長度開始,列舉原先每根木棍的可能長度,一直到(剪枝一:) 總長度的一半(如果原先木棍的數量不為1,則原先木棍的長度必然小於所有木棍總長度的一半)。(小貼士:如果列舉完後,仍然沒有輸出答案,則直接輸出總長度即可)(因為如果一直到總長度的一半都沒有解,則說明原先的木棍就只有一根而已)
2、從(剪枝二)最長的木棍開始選擇(如從最短的木棍開始搜尋,會增加回溯次數,具體原因留給讀者自行思考),逐一遞減,如果當前已選擇的木棍的總長度加上目前準備選擇的木棍的長度小於等於需要的長度,則分別搜尋是否選擇選擇該木棍的情況(類似於01揹包)
4、具體情況見**:
#include using namespace std;
int num[500010],maxn,minn,sum;
int max(int x,int y)
int min(int x,int y)
void dfs(int wait,int already,int need,int can)
if(already==need)
for(i=can;i>=minn;i--)
if(num[i] && i+already<=need)}
int main()
} temp=sum/2;
for(i=maxn;i<=temp;i++) //列舉每一種可能選定的長度
if(sum%i==0)
dfs(sum/i,0,i,maxn);
printf("%d",sum);
return 0;
}
P1120 小木棍 資料加強版
原題鏈結 不得不說,這題真的是一道深度搜尋毒瘤題qwq,整整坑了我乙個上午。先說一下大體思路 1.讀入資料的同時 注意過濾掉長度大於50的木棍 算出所有小木棍的總和sum,因為至少所有的小木棍會拼成一根長度為sum的超大木棍 2.找出所有小木棍中長度最大的那根max,原始長度len一定大於等於這個m...
P1120 小木棍 資料加強版
一道不錯的剪枝題,用到的剪枝優化比較多,剪枝思路也值得學習 在這裡我只採取了能通過此題的剪枝,似乎還可以繼續優化?剪枝講解在注釋裡 include include include include includeusing namespace std const int maxn 70 inline ...
P1120 小木棍 資料加強版
喬治有一些同樣長的小木棍,他把這些木棍隨意砍成幾段,直到每段的長都不超過 505050 現在,他想把小木棍拼接成原來的樣子,但是卻忘記了自己開始時有多少根木棍和它們的長度。給出每段小木棍的長度,程式設計幫他找出原始木棍的最小可能長度。輸入格式 共二行。第一行為乙個單獨的整數n表示砍過以後的小木棍的總...