AcWing338 计数问题(数位dp)
一道经典的数位dp,我们想要知道各个数分别是多少,不如通过枚举,每次判断一个数。
这题需要判断前导0,我们是否判断前导0的原因就是要看这个0会不会对答案产生影响
这题我们要求0的个数,显然必须判断前导0,例如windy数,前后差值的关系,显然也要判断
但是像数字游戏这类问题就不需要判断,因为不影响
#include<iostream> #include<string> #include<cstring> using namespace std; string l,r,s; int f[20][11][2][2]; int x; int len; int dfs(int cur,int n1,int flag,int g){ if(cur==len) return n1; auto &a=f[cur][n1][flag][g]; if(a!=-1) return a; int v=9; if(flag) v=s[cur]-'0'; int i; int ans=0; for(i=0;i<=v;i++){ if(g){ if(!i) ans+=dfs(cur+1,0,flag&&(i==v),1); else ans+=dfs(cur+1,n1+(i==x),flag&&(i==v),0); } else ans+=dfs(cur+1,n1+(i==x),flag&&(i==v),0); } return a=ans; } int solve(string t){ s=t; len=s.size(); memset(f,-1,sizeof f); return dfs(0,0,1,1); } int check(string s){ int ans=0; int i; for(i=0;i<s.size();i++){ if(s[i]-'0'==x) ans++; } return ans; } int main(){ int i; while(cin>>l>>r){ if(l=="0"&&r=="0") break; if(l.length()>r.length()||(l.length()==r.length()&&l>r)) swap(l,r); int ans=0; for(x=0;x<=9;x++){ ans=solve(r)-solve(l)+check(l); cout<<ans<<" "; } cout<<endl; } }
没有人不辛苦,只有人不喊疼