dp[i][3],其中i表示位数,后面的3表示有三种数 0:首位不带9的合法数 1:首位带9的合法数 2:不合法数
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 typedef long long LL; 6 int const N = 20; 7 LL dp[N][3],n,pow10[20];//0合法的数字个数 1以9开头的合法数字 2不合法的数字 8 int bit[N],t; 9 void pre() 10 { 11 dp[0][0]=1,dp[0][1]=0,dp[0][2]=0; 12 dp[1][0]=9,dp[1][1]=1,dp[1][2]=0; 13 for(int i=2;i<=19;i++) 14 { 15 dp[i][0]=dp[i-1][0]*9+dp[i-1][1]*8;//i-1位不以9开头数字前可添加9种数字 i-1位以9开头数字前可添加8种数字 16 dp[i][1]=dp[i-1][0]+dp[i-1][1];//i-1位不以9开发数字前添加9 i-1位以9开头数字前添加9 17 dp[i][2]=dp[i-1][2]*10+dp[i-1][1];//i-1位不合法数字前可添加10种数字 i-1位以9开头数字前添加4构成不合法数 18 } 19 } 20 LL getsum(LL z) 21 { 22 LL ans=z; 23 t=0; 24 for(;ans;ans/=10)bit[++t]=ans%10; 25 int flag=0,pre=0; 26 while(t) 27 { 28 ans+=dp[t-1][2]*bit[t]; 29 if(flag) 30 { 31 ans+=(dp[t-1][0]+dp[t-1][1])*bit[t]; 32 } 33 else 34 { 35 if(bit[t]>4) 36 ans+=dp[t-1][1]; 37 } 38 if(pre==4&&bit[t]==9) 39 flag=1; 40 pre=bit[t]; 41 t--; 42 } 43 return ans; 44 } 45 int main() 46 { 47 int T; 48 pre(); 49 scanf("%d",&T); 50 while(T--) 51 { 52 scanf("%I64d",&n); 53 printf("%I64d\n",getsum(n+1));//由于getsum(n)只能算出n-1中不合法的个数,所以要+1 54 } 55 return 0; 56 }