这大概是我复赛前看过的题了,那个时候的我其实还不是很会打搜索,甚至认为搜索,枚举的效率都是很低的,是不能够把题AC的,后来为了改变这种看法(其实是因为我发现一些我想不出的题的AC程序里大多有搜索,枚举的算法,格外揪心,没想到竟这么简单)。才做了一些搜索的题。这就是那些年曾令我揪心的题之一,想不出,去百度,这么简单,心碎了。的确搜索如果剪枝做的好的话,是可以把一些题目AC的。
、 好吧!可打完后提交的第一次还是TLE了,心好累。去别人的博客园看了一下,其实大家都差不多。仔细一看才发现别人是降序的,而我是升序的。这估计就是这题的一点小技巧吧!弄完后,AC了,既然经验在此,就积累了吧,毕竟积少成多。
1 #include2 #include 3 #include 4 #include 5 #include 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< <