数位DP JZOJ 3316. 非回文数字
题目
分析
- 第一道数位DP
- 模板直接套
代码
1 #include<iostream> 2 #include<cstring> 3 #define ll long long 4 using namespace std; 5 ll a[100],pos; 6 ll f[20][10][10][2][2][2]; 7 ll dfs(ll pos,ll pre2,ll pre1,bool zero2,bool zero1,bool lim) //zero为标记前导零是否存在 8 { 9 if (f[pos][pre2][pre1][zero1][zero2][lim]!=-1) 10 return f[pos][pre2][pre1][zero1][zero2][lim]; //记忆化搜索 11 ll ans=0; 12 if (pos<1) return 1; 13 ll end=lim?a[pos]:9; 14 for (ll i=0;i<=end;i++) 15 { 16 if ((zero2||i!=pre2)&&(zero1||i!=pre1)) //因为存在0就无法成为串 17 ans+=dfs(pos-1,pre1,i,zero1,zero1&&(i==0),lim&&i==end); 18 } 19 if (f[pos][pre2][pre1][zero1][zero2][lim]==-1) f[pos][pre2][pre1][zero1][zero2][lim]=ans; 20 return ans; 21 } 22 ll calc(ll x) 23 { 24 pos=0; 25 memset(f,-1,sizeof(f)); 26 while (x) a[++pos]=x%10,x/=10; 27 return dfs(pos,0,0,1,1,1); 28 } 29 int main () 30 { 31 ll l,r; 32 cin>>l>>r; 33 cout<<calc(r)-calc(l-1); 34 }
数位Dp模板
1 ll dfs(int cut,bool limit,bool sta) 2 { 3 if(cut==0) return 1; 4 ll ans=0; 5 int cu=limit?a[cut]:9; 6 for(int i=0;i<=cu;i++) 7 { 8 if(i==2 && sta) continue; 9 if(i!=4) 10 ans+=(dfs(cut-1, limit & (i==a[cut]) ,i==6)); 11 } 12 return ans; 13 } 14 15 ll solve(ll x) 16 { 17 int cut=0; 18 while(x){ 19 a[++cut]=(x%10); 20 x/=10; 21 } 22 return dfs(cut,1,0); 23 } 24 25 int main() 26 { 27 ll a,b; 28 while(1) 29 { 30 cin>>a>>b; 31 if(a==0 && b==0) return 0; 32 cout<<solve(b)-solve(a-1)<<endl; 33 } 34 35 return 0; 36 }
为何要逼自己长大,去闯不该闯的荒唐