给出n,问所有[0,n]区间内的数中,不含有49的数的个数
数位dp,记忆化搜索
dfs(int pos,bool pre,bool flag,bool e)
pos:当前要枚举的位置
pre:当前要枚举的位置的前面是否为4
flag:枚举当前时,这个数的49时候被算过了
e:当前位置是否可以随便取值
dp[pos][pre][flag]
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define ull unsigned long long using namespace std; const int maxn=66; ull dp[maxn][2][2]; int a[maxn]; ull solve(ull ); int main() { memset(dp,-1,sizeof dp); //先初始化 int test; cin>>test; while(test--){ ull n; cin>>n; cout<<solve(n)<<endl; } return 0; } ull dfs(int pos,bool pre,bool flag,bool e) { if(!pos) return flag; //不是返回0 if(e && dp[pos][pre][flag]!=-1) return dp[pos][pre][flag]; int last=e?9:a[pos]; ull ret=0; for(int i=0;i<=last;i++){ ret+=dfs(pos-1,i==4,flag||(pre&&i==9),e||(!e&&i<last)); } if(e) dp[pos][pre][flag]=ret; return ret; } ull solve(ull n) { int len=0; while(n){ a[++len]=n%10; n/=10; } return dfs(len,0,0,0); }