洛谷 P1120 小木棍 資料加強版 解題報告

2022-04-30 06:39:12 字數 1369 閱讀 4291

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

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

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

輸入檔案共有二行。

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

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

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

輸出檔案僅一行,表示要求的原始木棍的最小可能長度

資料時限修改:

-#17 #20 #22 #27 四組資料時限500ms

-#21 #24 #28 #29 #30五組資料時限1000ms

其他時限改為200ms(請放心食用)

這是乙個無比毒瘤的搜尋題

------序

我們列舉每乙個長度\(l\),用爆搜檢查這個長度\(l\)是否合法。

關於毒瘤減枝:

剪枝1:\(l\)如果不整除\(sum\),直接再見。這點很容易想到

剪枝2:列舉上下界為\(max\-sum/2\),下界很容易想明白,而上界只是優化了下常數和減枝1一樣的。

剪枝3:將木棍從大到小排序進行列舉。這個減枝是以下所有減枝的前提。

剪枝4:在湊成某根木棍時,從它上一次用的木棍編號的下一位開始列舉,因為反過來是一樣的。

剪枝5:如果某個長度和上乙個長度一樣且上乙個長度的沒有用,那麼這個也不能用。

剪枝6:維護乙個字尾和陣列\(p[i]\),如果當前長度加上最後所有能用的和還不夠木棍原長,不能用。

剪枝7:如果從當前編號列舉完整的棍子失敗了以後,因為每個殘棍都得用上,所以不行。

剪枝8:這是乙個貪心性減枝。如果當前長度加上列舉長度失敗了以後,不用往後列舉了。

因為哪怕後面有更小的能代替這個列舉長度,也不可能產生更優的結果了。因為更短的長度明顯有更多選擇。

code:

#include #include #include using namespace std;

const int n=70;

int n,a[n],sum=0,s,len,ans=0,p[n],used[n];

bool cmp(int x1,int x2)

void dfs(int last,int k,int l)//剪枝4

if(k==s+1)

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

}printf("%d\n",sum);

return 0;

}

2018.5.22

洛谷 P1120 小木棍 資料加強版

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

洛谷 P1120 小木棍 資料加強版

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

洛谷P1120 小木棍 資料加強版

喬治有一些同樣長的小木棍,他把這些木棍隨意砍成幾段,直到每段的長都不超過50。現在,他想把小木棍拼接成原來的樣子,但是卻忘記了自己開始時有多少根木棍和它們的長度。給出每段小木棍的長度,程式設計幫他找出原始木棍的最小可能長度。共二行。第一行為乙個單獨的整數n表示砍過以後的小木棍的總數,其中n 65 管...