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