Ural(Timus) 1012. K-based Numbers. Version 2

DP+高精度  (和1009是一样的题目,不过数字的位数达到了180,所以要用高精度)

同样是记忆化搜索实现,不过加入了高精度,一些细节地方就注意一下。我的代码写的不好,有点长有点乱…………

 

#include <cstdio>

#include <cstring>

#define LEN 210  //高精度数组的大小

#define MAX 210  //位数

struct num

{

    int a[LEN],len; //a数组保存高精度

}dp[MAX][15];  //最多180位,最高进制为10

int N,K;



void init()

{

    for(int i=1; i<N; i++)

        for(int j=0; j<K; j++)

        {

            memset(dp[i][j].a,0,sizeof(dp[i][j].a));

            dp[i][j].len=-1;

        }

    for(int i=0; i<K; i++)

    {

        dp[N][i].len=1;

        memset(dp[N][i].a,0,sizeof(dp[N][i].a));

        dp[N][i].a[0]=1;

    }

    return ;

}



void add(struct num p ,struct num q , struct num *ans)

{

    struct num tmp;

    if(q.len>p.len) { tmp=q; q=p; p=tmp; }

    int t,c=0;

    for(int i=0; i<p.len; i++)

    {

        t=p.a[i]+q.a[i]+c;

        (*ans).a[i]=t%10;

        c=t/10;

    }

    (*ans).len=p.len;

    if(c>0)

    {

        (*ans).a[p.len]=1;

        (*ans).len++;

    }

    return ;

}



void dfs(int i , int j)

{

    if(dp[i][j].len!=-1)

        return ;

    dp[i][j].len=0;



    for(int k=1; k<K; k++)

    {

        dfs(i+1,k);

        //dp[i][j]+=dp[i+1][k]

        add(dp[i][j] , dp[i+1][k] , &dp[i][j]);

    }

    if(j)

    {

        dfs(i+1,0);

        //dp[i][j]+=dp[i+1][0];

        add(dp[i][j] , dp[i+1][0] , &dp[i][j]);

    }

    return ;

}



void solve()

{

    struct num ans;

    memset(ans.a,0,sizeof(ans.a)); ans.len=0;

    

    for(int i=1; i<K; i++)

    {

        dp[1][i].len=0;

        for(int j=0; j<K; j++)

        {

            dfs(2,j);

            //dp[1][i]+=dp[2][j]

            add(dp[1][i] , dp[2][j] , &dp[1][i]);

        }

        add(ans , dp[1][i] , &ans);

    }



    for(int i=ans.len-1; i>=0; i--)

        printf("%d",ans.a[i]);

    printf("\n");

}



int main()

{

    while(scanf("%d%d",&N,&K)!=EOF)

    {

        init();

        solve();

    }

    return 0;

}

 

你可能感兴趣的:(version)