这大概是我复赛前看过的题了,那个时候的我其实还不是很会打搜索,甚至认为搜索,枚举的效率都是很低的,是不能够把题AC的,后来为了改变这种看法(其实是因为我发现一些我想不出的题的AC程序里大多有搜索,枚举的算法,格外揪心,没想到竟这么简单)。才做了一些搜索的题。这就是那些年曾令我揪心的题之一,想不出,去百度,这么简单,心碎了。的确搜索如果剪枝做的好的话,是可以把一些题目AC的。
、 好吧!可打完后提交的第一次还是TLE了,心好累。去别人的博客园看了一下,其实大家都差不多。仔细一看才发现别人是降序的,而我是升序的。这估计就是这题的一点小技巧吧!弄完后,AC了,既然经验在此,就积累了吧,毕竟积少成多。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<set> 6 #define maxn 70 7 #define rep(i,j,k) for(int i = j; i <= k; i++) 8 #define st stick[i] 9 using namespace std; 10 11 int stick[maxn] = {0}, n, used[maxn] = {0}, ch, mu; 12 int unable[maxn] = {0}; 13 14 bool bmp(int a,int b) 15 { 16 return a > b; 17 } 18 19 inline int read() 20 { 21 int s = 0, t = 1; 22 char c = getchar(); 23 while( !isdigit(c) ){ 24 if( c == '-' ) t = -1; 25 c = getchar(); 26 } 27 while( isdigit(c) ){ 28 s = s * 10 + c - '0'; 29 c = getchar(); 30 } 31 return s * t; 32 } 33 34 bool match(int sheng,int x,int ci) 35 { 36 if( !sheng ) ci++, x = 0, sheng = ch; 37 if( ci == mu ) return 1; 38 rep(i,x,n-1){ 39 if( st <= sheng && !used[i] ){ 40 used[i] = 1; 41 if( match(sheng-st,i+1,ci) ) return 1; 42 else if( x == 0 ) { 43 used[i] = 0; return 0; 44 } 45 used[i] = 0; 46 int j = i; while( stick[j+1] == stick[i] ) j++; i = j; 47 } 48 } 49 return 0; 50 } 51 52 int main() 53 { 54 n; 55 while( scanf("%d", &n) == 1 && n ){ 56 int sum = 0; 57 rep(i,0,n-1){ 58 st = read(); 59 sum += st; 60 used[i] = 0; 61 } 62 sort(stick,stick+n,bmp); 63 int maxl = stick[0]; 64 rep(i,maxl,sum){ 65 if( sum % i == 0 ){ 66 ch = i; 67 mu = sum / i; 68 if( match(i,0,0) ){ 69 cout<<i<<endl; 70 break; 71 } 72 } 73 } 74 } 75 return 0; 76 }