标签:数位dp
3 1 50 500
0 1 15这是一道数位dp,比62要简单一些。#include<stdio.h> #include<string.h> __int64 dp[25][5]; int a[20]; void init() { int i,j; dp[0][0]=1; //这里dp[0][0]=1还是挺重要的,讨论这个数的个位时有用 dp[1][0]=10;dp[1][1]=1;dp[1][2]=0; for(i=2;i<=20;i++){ dp[i][0]=dp[i-1][0]*10-dp[i-1][1];//表示不超过i位数的不带49的数 dp[i][1]=dp[i-1][0]; //表示不超过i位数的不带49且最高位为9的数 dp[i][2]=dp[i-1][2]*10+dp[i-1][1];//表示不超过i位数的带49的数 } } __int64 cal(__int64 n) //计算的是[0,n-1],其中n是不是含49的数没有判断也没有算进去 { int i,j,len=0,flag; __int64 num=0; memset(a,0,sizeof(a)); while(n){ a[++len]=n%10;n=n/10; } if(len==1)return 0; flag=0; //判断是否前面已经有49了 for(i=len;i>=1;i--){ num=num+a[i]*dp[i-1][2]; if(flag)num=num+a[i]*dp[i-1][0]; if(!flag && a[i]>4) num=num+dp[i-1][1]; if(a[i]==9 && a[i+1]==4) flag=1; } return num; } int main() { int T,m,i,j; __int64 n; init(); scanf("%d",&T); while(T--) { scanf("%I64d",&n); printf("%I64d\n",cal(n+1)); } return 0; }
标签:数位dp
原文地址:http://blog.csdn.net/kirito_acmer/article/details/45219747