BNU 1111(dfs+剪枝)

来源:互联网 发布:蓝牙小车单片机程序 编辑:程序博客网 时间:2024/06/05 18:25
//题意:给定n  让你找到最短的序列1 , 2, ....................., n 使得每个数都可由它之前的任意两个数相加得到//方法dfs+剪枝#include <iostream>#include "stdio.h"#include "stdlib.h"#include "string.h"#include "algorithm"#include <queue>#define N 100005using namespace std;void dfs(int ans[], int len, int &limit, int n, int sub[] ){    if( len >= limit ) return;    for(int i = len - 1; i >= 0; -- i) //向前枚举    {        ans[len] = ans[len - 1] + ans[i];        if(ans[len] == n){ //如果找到了  就更新limit并返回            if(len + 1 <= limit )            {                limit = len + 1;                for( int j = 0; j <= len; j++)                    sub[j] = ans [j] ;            }             return ;        }        else if( ans[len] < n) //如果找不到 就继续dfs            dfs(ans, len+1, limit, n, sub);    }}int main(){    int n;    int ans[100];    int sub[100];    while(scanf("%d",&n)&&n)    {        if( n == 1 )  {printf("1\n");continue;}        else if( n == 2 ) {printf("1 2\n");continue;}        int tmp, limit;        tmp=n, limit=0;        while( tmp ) //找到最大的长度  得到的limit就是最大的长度        {            if( tmp%2 ) tmp--;            else tmp >>= 1;            limit++;        }        ans[0] = 1; ans[1] = 2;        dfs(ans, 2, limit, n, sub);        for(int i = 0; i < limit; i++)            if(i < limit-1 ) printf("%d ",sub[i]);            else printf("%d\n", sub[i]);    }    return 0;}

0 0
原创粉丝点击