P1120-小木棍 [数据加强版]
吸口氧气才能过
1 #include <bits/stdc++.h> 2 #define _for(i,a,b) for(int i = (a);i < b;i ++) 3 #define _rep(i,a,b) for(int i = (a);i > b;i --) 4 #define INF 0x3f3f3f3f 5 typedef long long ll; 6 using namespace std; 7 inline ll read() 8 { 9 ll ans = 0; 10 char ch = getchar(), last = ' '; 11 while(!isdigit(ch)) last = ch, ch = getchar(); 12 while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); 13 if(last == '-') ans = -ans; 14 return ans; 15 } 16 inline void write(ll x) 17 { 18 if(x < 0) x = -x, putchar('-'); 19 if(x >= 10) write(x / 10); 20 putchar(x % 10 + '0'); 21 } 22 int N; 23 int a[66],Next[66],vis[66]; 24 int aend = 0; 25 int sum = 0; 26 int num; 27 bool dfs(int k,int la,int re) 28 { 29 if(!re) 30 { 31 if(k==num) return true; 32 33 _for(i,1,aend+1) 34 if(!vis[i]) 35 { 36 vis[i] = 1; 37 if(dfs(k+1,i,(sum/num)-a[i])) return true; 38 else 39 { 40 vis[i] = 0; 41 return false; 42 } 43 } 44 return false; 45 } 46 47 int t = lower_bound(a+la,a+aend+1,re,greater<int>())-a; 48 _for(i,t,aend+1) 49 if(!vis[i]) 50 { 51 vis[i] = 1; 52 if(dfs(k,i,re-a[i])) return true; 53 vis[i] = 0; 54 55 if(re==a[i] || re==sum/num) return false; 56 i = Next[i]; 57 if(i==aend) return false; 58 } 59 return false; 60 } 61 int main() 62 { 63 N = read(); 64 int t; 65 _for(i,1,N+1) 66 { 67 t = read(); 68 if(t>50) 69 continue; 70 a[++aend] = t; 71 sum += a[aend]; 72 } 73 sort(a+1,a+aend+1,greater<int>()); 74 75 Next[aend] = aend; 76 _rep(i,aend-1,0) 77 { 78 if(a[i]==a[i+1]) Next[i] = Next[i+1]; 79 else Next[i] = i; 80 } 81 82 memset(vis,0,sizeof(vis)); 83 int rnt = sum; 84 _for(len,a[1],sum/2+1) 85 { 86 if(sum % len != 0) continue; 87 num = sum/len; 88 vis[1] = 1; 89 if(dfs(1,1,len-a[1])) 90 { 91 rnt = len; 92 break; 93 } 94 vis[1]= 0; 95 } 96 write(rnt); 97 return 0; 98 }