HDU 1455 Sticks(DFS,剪枝,原來木棒的至少長度)
阿新 • • 發佈:2019-02-19
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9115 Accepted Submission(s): 2700
Problem Description George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.
Input
The input contains blocks of 2 lines. The first line contains the number of sticks parts after cutting, there are at most 64 sticks. The second line contains the lengths of those parts separated by the space. The last line of the
file contains zero.
Output The output file contains the smallest possible length of original sticks, one per line.
Sample Input 9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
Sample Output 6 5
Source
Problem Description George took sticks of the same length and cut them randomly until all parts became at most 50 units long. Now he wants to return sticks to the original state, but he forgot how many sticks he had originally and how long they were originally. Please help him and design a program which computes the smallest possible original length of those sticks. All lengths expressed in units are integers greater than zero.
Input
Output The output file contains the smallest possible length of original sticks, one per line.
Sample Input 9 5 2 1 5 2 1 5 2 1 4 1 2 3 4 0
Sample Output 6 5
Source
題意:
給我們一組凌亂的木棒,這些木棒是由一些相同長度的木棒切成的,讓我們現在找出原先那些相同長度木棒至少多短。。。。
思路:
這樣應該是屬於比較繁瑣的 DFS 了,剪枝(優化)少了容易超時。
程式碼:
#include<cstdio> #include<cstring> #include<algorithm> #define MYDD 128 using namespace std; int total,l;//給定木棒能夠達到的組數,木棒的最小可能長度即答案 int n,sum;//木棒的個數,木棒總長度 struct Sti { int length;//長度 int mark;//是否已經使用 } stick[MYDD]; bool cmp_length(Sti x,Sti y) { return x.length>y.length;//給定的木棒長度按照從長到短排序 } int DFS(int s,int len,int location) { // s 已組成的木棒數目,len已達到的長度,location搜尋木棒的下標位置 if(s==total) return 1; for(int j=location+1; j<n; j++) { if(stick[j].mark) continue;//木棒已經用過 if(len+stick[j].length==l) { stick[j].mark=1; if(DFS(s+1,0,-1)) return 1; stick[j].mark=0; return 0; } else if(len+stick[j].length<l) { stick[j].mark=1; if(DFS(s,len+stick[j].length,j)) return 1; stick[j].mark=0; if(len==0)//當前搜尋,如果前面的len為0,但第一根沒有用上,那麼這根木棒就要捨棄 return 0; while(stick[j].length==stick[j+1].length) j++;//剪枝:這根不滿足,則長度相同的也不滿足 } } return 0; } int main() { while(scanf("%d",&n)&&n) { sum=0; for(int j=0; j<n; j++) { scanf("%d",&stick[j].length); sum+=stick[j].length; stick[j].mark=0;//標記木棒暫未使用 } sort(stick,stick+n,cmp_length); for(l=stick[0].length; l<=sum; l++) { if(sum%l!=0) continue;//剪枝:如果不能夠整除就沒有整數解,換到下一個 total=sum/l;//得到木棒總數目 if(DFS(1,0,-1)) { //已經使用 1 個木棒,組成的長度為 0 ,從結構體陣列下標 0 開始遍歷 printf("%d\n",l); break; } } } return 0; }