Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 7921 Accepted Submission(s): 2778
1 //#define LOCAL 2 #include<cstdio> 3 #include<cstring> 4 #define LL __int64 5 using namespace std; 6 const int maxn=25; 7 LL dp[maxn][3]={0}; 8 int nn[maxn]; 9 int main() 10 { 11 12 #ifdef LOCAL 13 freopen("test.in","r",stdin); 14 #endif 15 int cas,i; 16 LL n; 17 scanf("%d",&cas); 18 /*数位DP的惯有模式预处理*/ 19 dp[0][0]=1; 20 for(i=1;i<=20;i++) 21 { 22 dp[i][0]=dp[i-1][0]*10-dp[i-1][1]; 23 dp[i][1]=dp[i-1][0]; 24 dp[i][2]=dp[i-1][2]*10+dp[i-1][1]; 25 } 26 while(cas--) 27 { 28 scanf("%I64d",&n); 29 i=0; 30 n+=1; 31 memset(nn,0,sizeof(nn)); 32 while(n>0) 33 { 34 nn[++i]=n%10; 35 n/=10; 36 } 37 LL ans=0; 38 bool tag=0; 39 int num=0; 40 for( ; i>=1 ; i-- ) 41 { 42 ans+=dp[i-1][2]*nn[i]; /*计算49开头的个数*/ 43 if(tag){ 44 ans+=dp[i-1][0]*nn[i]; /*当前面出现了49的时候,那么后面出现的任何数字也要进行统计*/ 45 } 46 if(!tag&&nn[i]>4) 47 { 48 ans+=dp[i-1][1]; /*如果没有出现49开头,只要首部大于5,那么必定保函有一个49*/ 49 } 50 if(num==4&&nn[i]==9) 51 tag=1; 52 num=nn[i]; 53 } 54 printf("%I64d\n",ans); 55 } 56 return 0; 57 }
原文:http://www.cnblogs.com/gongxijun/p/3997533.html