1. 程式人生 > >解題:洛谷1120 小木棍

解題:洛谷1120 小木棍

code targe -- 新的 += ref i++ problem algo

題面

這個題剪枝比較多的說=。=

1.記錄最長和最短的木棍,限制枚舉的上下界

2.記錄木棍的總長$tot$度,只在其能被枚舉的長度整除時搜索

3.從長到短枚舉長度(暫時好像沒啥用)

4.每次(不是新的一根木棍時)從上次枚舉的長度開始枚舉(和3組合起來用的)

5.(強剪枝來了)如果是在嘗試拼一根新木棍,那麽只要沒拼出來就拼不出來了(這個時候沒有可以回溯的狀態)

6.(也是一個強剪枝,和上面的一個道理)如果恰好拼出一根新木棍就拼不出來了,也是一定拼不出來了

技術分享圖片
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4
using namespace std; 5 int cnt[60]; 6 int n,rd,len,tot,num,maxx,mini=1e9; 7 bool DFS(int noww,int lenh,int last) 8 { 9 if(noww==num) return true; 10 for(int i=last;i>=mini;i--) 11 if(cnt[i]&&lenh+i<=len) 12 { 13 cnt[i]--; int tmp=lenh+i; 14 if
(tmp==len) {if(DFS(noww+1,0,maxx)) return true;} 15 else {if(DFS(noww,tmp,i)) return true;} cnt[i]++; 16 if(!lenh||lenh+i==len) return false; 17 } 18 return false; 19 } 20 int main () 21 { 22 scanf("%d",&n); 23 for(int i=1;i<=n;i++) 24 { 25 scanf("
%d",&rd); 26 if(rd<=50) 27 { 28 cnt[rd]++,tot+=rd; 29 maxx=max(maxx,rd); 30 mini=min(mini,rd); 31 } 32 } 33 bool found=false; 34 for(int i=maxx;i<=tot;i++) 35 if(tot%i==0) 36 { 37 len=i,num=tot/i; 38 if(DFS(0,0,maxx)) 39 { 40 printf("%d",i); 41 found=true; break; 42 } 43 } 44 if(!found) printf("%d",tot); 45 return 0; 46 }
View Code

解題:洛谷1120 小木棍