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