思路:数位DP
提交:\(2\)次
错因:进行下一层\(dfs\)时的状态转移出错
题解:
还是记忆化搜索就行,但是要用\(map\)记忆化。
见代码
#include<cstdio> #include<iostream> #include<map> #define R register int #define ll long long using namespace std; namespace Luitaryi { template<class I> inline I g(I& x) { x=0; register I f=1; register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f; do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f; } ll n,l,r,num[19],len,stk[19],top; map<ll,ll> f[20]; inline void print() { for(R i=1;i<=top;++i) cout<<stk[i]; } inline ll dfs(int l,bool ul,bool ck,ll ml) { if(l==0) {return ml<=n&&ml>0?1:0;} if(!ul&&!ck&&f[l].count(ml)) return f[l][ml]; R mx=ul?num[l]:9; register ll cnt=0; for(R i=0;i<=mx;++i) if(ck&&i==0) stk[++top]=i,cnt+=dfs(l-1,ul&&i==mx,true,0),--top;//一直是前导零 else if(ck&&i!=0) stk[++top]=i,cnt+=dfs(l-1,ul&&i==mx,false,i),--top;//第一次不是前导零 else if(!ck&&i!=0) stk[++top]=i,cnt+=dfs(l-1,ul&&i==mx,false,ml*i),--top;//之前有不是前导零的时刻 //注意到i=0且不是前导零时就不必向下dfs了 return f[l][ml]=cnt; } inline ll solve(ll x) { len=0; for(R i=1;i<=19;++i) f[i].clear(); while(x) num[++len]=x%10,x/=10; return dfs(len,1,1,0); } inline void main() {g(n),g(l),g(r); printf("%lld\n",solve(r-1)-solve(l-1));} } signed main() {Luitaryi::main(); return 0;}
2019.08.16
84