HDU 3555 Bomb 数位DP 入门

时间:2023-01-22 03:46:56

给出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=; ull dp[maxn][][];
int a[maxn]; ull solve(ull ); int main()
{
memset(dp,-,sizeof dp); //先初始化
int test;
cin>>test;
while(test--){
ull n;
cin>>n;
cout<<solve(n)<<endl;
}
return ;
} ull dfs(int pos,bool pre,bool flag,bool e)
{
if(!pos)
return flag; //不是返回0
if(e && dp[pos][pre][flag]!=-)
return dp[pos][pre][flag]; int last=e?:a[pos];
ull ret=;
for(int i=;i<=last;i++){
ret+=dfs(pos-,i==,flag||(pre&&i==),e||(!e&&i<last));
}
if(e)
dp[pos][pre][flag]=ret;
return ret;
} ull solve(ull n)
{
int len=;
while(n){
a[++len]=n%;
n/=;
}
return dfs(len,,,);
}