zoukankan      html  css  js  c++  java
  • Ural(Timus) 1013. Kbased 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;
    }
  • 相关阅读:
    1023. 组个最小数
    1021. 个位数统计
    *1020. 月饼
    *1019. 数字黑洞
    1016. 部分A+B
    *1014. 福尔摩斯的约会
    *1013. 数素数
    *1012. 数字分类
    1011. A+B和C
    *1008. 数组元素循环右移问题
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2870377.html
Copyright © 2011-2022 走看看