Ural(Timus) 1013. K-based Numbers. Version 3

DP+高精度+滚动数组

还是1009的题目,不过数据再大点,数组都开不下,需要滚动数组。

回想1009的递推的方式,可以看到,要知道当前位的信息,只需要知道前一位的信息即可,所以其实任何时候都只需要两位,所以我们可能用户滚动数组,不断替换,而算法思想是完全不变的

 

//用递推来实现,要得到当前位的信息只与前一位有关,因为用滚动数组,只保存两位,不断滚动

//dp[0][]表示前一位的信息,dp[1][]表示当前位的信息,每一位的数字只能为0和非0

#include <cstdio>

#include <cstring>

#define MAX 1900  //位数

#define LEN 20000  //高精度的位数

struct num

{

    int a[LEN],len;

}dp[2][2];



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

{

    struct num tmp;

    if(p.len<q.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)

    {

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

        (*ans).len++;

    }

    return ;

}

void mul(int m , struct num p , struct num *ans)

{

    int t,c=0;

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

    {

        t=p.a[i]*m+c;

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

        c=t/10;

    }

    (*ans).len=p.len;

    if(c)

    {

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

        (*ans).len++;

    }

    return ;

}

int main()

{

    int N,K;

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

    {

        memset(dp,0,sizeof(dp));

        //dp[0][1]=K-1; dp[0][0]=0;

        dp[0][1].len=1; dp[0][1].a[0]=K-1;

        dp[0][0].len;

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

        {

            struct num tmp;

            //dp[1][1]=(K-1)*(dp[0][0]+dp[0][1]);

            add(dp[0][0],dp[0][1],&tmp);

            mul(K-1,tmp,&dp[1][1]);

            dp[1][0]=dp[0][1];



            dp[0][0]=dp[1][0];

            dp[0][1]=dp[1][1];

        }

        struct num ans;



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

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

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

        printf("\n");

    }

    return 0;

}

 

你可能感兴趣的:(version)