Main topic:
There is a set of n different numbers consisting of several strings: A1,a2,a3...an.
1. An array of B.
2. The first operation we assign the value of B0 to A1. After we have a n-1 operation, the K operation we will BY=BI+BJ (Y,i,j may be the same).
3. After each operation, we take out by in turn. Make a new string in order.
When the operation is finished, we can get a new string that is the same as the a number string. If you can output the minimum length required for array B. Conversely output-1.
Ideas:
First introduce a pure DFS algorithm: enumerate i,j,y each time, but will T.
However, it can be found that the number in B must have appeared in a. Therefore, the memory search, state (s) is stored in A1 to an IS in B, then the number of S in 1 is the length of B. Then Dfs, of course, needs to be searched only once for each state.
Remember: BY,BI,BJ can take any of the existing B!
There are two ways of doing this:
1. Follow, each check for the K can be obtained, after DFS, but check the complexity of the higher.
2. Backward, backward from the nth number, take the smallest of the sub-state, and then judge with the current.
Code:
Down:
1#include <cstdio>2 intn,i,ans,a[ -],mi[ -];3 BOOLvis[1<< at];4 5 BOOLCheckintSintk)6 {7 for(intI=0; i<n;++i)8 for(intj=i;j<n;++j)9 if((mi[i]&s) && (mi[j]&s) && (A[i]+a[j]==a[k]))return 0;Ten return 1; One } A - voidDfsintKintS//s Status - { the if(Vis[s])return; - intI,cnt=0; vis[s]=1; - for(i=s;i;i=i>>1) cnt=cnt+ (i&1); - if(ans<=cnt)return; + if(k==n) {ans=cnt;return; } - if(check (S,K))return; +DFS (k +1, s|mi[k]); A for(i=0; i<n;++i) at if(S&mi[i]) Dfs (k +1, (S^mi[i]) |mi[k]); - } - - intMain () - { -scanf"%d",&n); in for(i=0; i<n;++i) scanf ("%d",&a[i]); - for(mi[0]=i=1; i<=n;++i) mi[i]=mi[i-1]<<1; toans= -; Dfs1,1); printf"%d\n",ans< -? ans:-1); + return 0; -}
Upside Down:
1#include <cstdio>2 Const intm= -;3 intn,i,a[m],mi[m],dp[1<<M];4 5 voidDfsintKints)6 {7 if(Dp[s])return;8Dp[s]=m;inti,j,t;9 for(i=0; i<k;++i)Ten for(j=i;j<k;++j) One if(a[i]+a[j]==A[k]) A { -T= (S-mi[k]) | Mi[i] | MI[J] | mi[k-1]; -DFS (K-1, T); the if(Dp[s]>dp[t]) dp[s]=Dp[t]; - } - for(t=0,i=s;i;i=i>>1) t=t+ (i&1); - if(dp[s]<t) dp[s]=T; + } - + intMain () A { atscanf"%d",&n); - for(mi[0]=i=1; i<=n;++i) mi[i]=mi[i-1]<<1; - for(i=0; i<n;++i) scanf ("%d",&a[i]); ---n,dp[1]=1, DFS (N,mi[n]); - if(dp[mi[n]]==m) printf ("-1\n"); - Elseprintf"%d\n", Dp[mi[n]]); in return 0; -}
Codeforces 279D The Minimum number of Variables puzzle