HDU P3555 Bomb【數位DP】
阿新 • • 發佈:2018-12-09
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;
const ll N=1e2+5;
ll n,m;
ll w[N],f[N][3 ];
inline ll read() {
ll x=0;char ch=getchar();bool f=0;
while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?-x:x;
}
ll dp(ll len,ll lim,ll flag) {
if(len==0) return lim==2;
if (!flag&&(~f[len][lim])) return f[len][lim];
ll ans=0,length;
if(flag) length=w[len];
else length=9;
rep(i,0,length) {
if(lim==2||(lim==1&&i==9)) ans+=dp(len-1,2,flag&&i==length);
else if(i==4) ans+=dp(len-1,1,flag&&i==length);
else ans+=dp(len-1,0,flag&&i==length);
}
if(!flag) f[len][lim]=ans;
return ans;
}
void solve(ll x) {
w[0]=0;
while(x) {
w[++w[0]]=x%10;x/=10;
}
printf("%lld\n",dp(w[0],0,1));
}
int main() {
memset(f,-1,sizeof(f));
n=read();
while(n--) {
m=read();
solve(m);
}
return 0;
}