据说是剪枝神题,不过剪枝确实是挺多的,少一个有可能都会超时。
1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 100; 7 int stick[N]; 8 bool used[N]; 9 int n, snum, slen; 10 11 bool dfs( int num, int len, int pos ) 12 { 13 if ( num == snum ) return true; 14 for ( int i = pos; i < n; i++ ) 15 { 16 if ( !used[i] ) 17 { 18 int tmp = stick[i] + len; 19 if ( tmp > slen ) continue; 20 used[i] = 1; 21 if ( tmp == slen ) 22 { 23 if ( dfs( num + 1, 0, 0 ) ) return true; 24 used[i] = 0; 25 return false; 26 } 27 else 28 { 29 if ( dfs( num, tmp, i + 1 ) ) return true; 30 used[i] = 0; 31 } 32 if ( len == 0 ) return false; 33 while ( stick[i] == stick[i + 1] ) i++; 34 } 35 } 36 return false; 37 } 38 39 bool cmp( int a, int b ) 40 { 41 return a > b; 42 } 43 44 int main () 45 { 46 while ( scanf("%d", &n), n ) 47 { 48 int sum = 0; 49 for ( int i = 0; i < n; i++ ) 50 { 51 scanf("%d", stick + i); 52 sum += stick[i]; 53 } 54 sort( stick, stick + n, cmp ); 55 stick[n] = -1; 56 int maxn = stick[0]; 57 for ( int i = maxn; i <= sum; i++ ) 58 { 59 if ( sum % i == 0 ) 60 { 61 snum = sum / i; 62 slen = i; 63 memset( used, 0, sizeof(used) ); 64 if ( dfs( 0, 0, 0 ) ) 65 { 66 printf("%d\n", i); 67 break; 68 } 69 } 70 } 71 } 72 return 0; 73 }
时间: 2024-11-04 22:37:42