Addition Chains
An addition chain for n is an integer sequence Addition Chains |

- a0 = 1
- am = n
- a01


For example, <1> and <1> are both valid solutions when you are asked for an addition chain for 5.1>1>
Input Specification
The input file will contain one or more test cases. Each test case consists of one line containing one integer n (
Output Specification
For each test case, print one line containing the required integer sequence. Separate the numbers by one blank.Hint: The problem is a little time-critical, so use proper break conditions where necessary to reduce the search space.
Sample Input
5 7 12 15 77 0
Sample Output
1 2 4 5 1 2 4 6 7 1 2 4 8 12 1 2 4 5 10 15 1 2 4 8 9 17 34 68 77
Iterative DFS + pruning
#include<stdio.h>
#include<cstring>
#include<cmath>
#include<string>
#include<ctime>
#include<vector>
#define REP(i, b, n) for (int i = b; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define DBG 0
using namespace std;
int N,CM;
int cnt[10001];
bool has[10001];
vector<int>mv,cv;
void print(){
bool ll=0;
rep(i,mv.size()){if(ll)printf(" ");ll=1;printf("%d",mv[i]);}
printf("\n");
}
bool DFS(int cur){
if(DBG)printf("dfs cur %d size %d\n",cur, cv.size());
if(cur==N){mv=cv;return 1;}
else{
int c,bc,k,j;
has[cur]=1;
rep(i,cv.size()){
c=cur+cv[i];
for(k=c,j=cv.size()+2;j<CM+1;k*=2,j++);
if(k<N)continue;
if(c<=N&&!has[c]&&cv.size()+1<=cnt[c]){
cnt[c]=cv.size()+1;
cv.push_back(c);
if(DFS(c))return 1;
cv.pop_back();
}
}
has[cur]=0;
return 0;
}
}
void init(){
memset(cnt,0x7f,sizeof(cnt));
}
int getNum(int a){
return int(ceil(log(a)/log(2)));
}
void ans(){
memset(has,0,sizeof(has));
cv.clear(),cv.push_back(1),CM=18,has[0]=1;
if(DBG)printf("cur %d\n",N);
int n=getNum(N);
REP(i,n,19){
mv.clear(),CM=i;
DFS(1);
if(mv.size())break;
}
print();
}
int main(){
int a;
init();
while(scanf("%d",&N)==1){
if(N==0)break;
ans();
}
//int t=clock();
//printf ("%f seconds.\n",((float)t)/CLOCKS_PER_SEC);
}
沒有留言:
張貼留言