数位dp hdu3555

#include <cstdio>
#include <cstring>
#include <set>
#include <iostream>
#include <map>
#include <math.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1000005;
int t,cnt,num[25];
ll n,dp[25][3];
void init(){
dp[0][0]=1;//31行有用到,必须要对其赋值

for(int i=1;i<=20;i++){
    dp[i][0]=dp[i-1][0]*10-dp[i-1][1];//每位数都要包括零在内才行
    dp[i][1]=dp[i-1][0];
    dp[i][2]=dp[i-1][2]*10+dp[i-1][1];
}
}
ll shuwei(){
if(n<49)
    return 0;
ll ans=0;
int flag=0;

for(int i=cnt;i>0;i--){//每次循环内求得是小于当前位置上的数的情况
    ans+=(ll)num[i]*dp[i-1][2];
    if(flag)
        ans+=(ll)num[i]*dp[i-1][0];
    else{
        if(num[i]>4)
            ans+=dp[i-1][1];
    }
  if(num[i+1]==4&&num[i]==9)
    flag=1;
}
return ans;
}
int main()
{
   // freopen("in.txt","r",stdin);
cin>>t;
init();
while(t--){
    scanf("%I64d",&n);
ll n1=n+1;//因为包括n,所以必须要n+1
    cnt=0;
    while(n1){
        num[++cnt]=n1%10;
        n1/=10;
    }
    num[cnt+1]=0;
    ll ans=shuwei();
    cout<<ans<<endl;


}
  return 0;
}

 

posted @ 2016-05-29 21:00  十目  阅读(193)  评论(0编辑  收藏  举报