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;
}

 

posted @ 2013-01-21 17:40  Titanium  阅读(317)  评论(0编辑  收藏  举报