[SCOI2009]windy数 数位dp
Code:
#include<cmath> #include<iostream> #include<cstdio> using namespace std; const int maxn=30; long long f[maxn][12]; void get_table(){ for(int i=0;i<=9;++i)f[1][i]=1; for(int i = 2 ; i <= 13 ; ++i) for(int j = 0; j <= 9; ++j) for(int last = 0; last <= 9; ++last) if(abs(j-last)>=2)f[i][j]+=f[i-1][last]; } int get_length(long long num){ int cnt=1; while(num/=10)++cnt; return cnt; } long long get_mod(int length){ long long res=1; for(int i=1;i<length;++i)res*=10; return res; } long long g(long long num,int length,int cur){ long long mod=get_mod(length); int current=num/mod; num-=(current*mod); if(cur>current)return 0; if(cur<current||length==1)return f[length][cur]; if(num==0){ if(length==2&&abs(current)>=2)return 1; //2 digit number return 0; } long long fin=0; for(int i=0;i<=9;++i) if(abs(i-cur)>=2)fin+=g(num,length-1,i); return fin; } long long solve(long long num){ int length=get_length(num); long long mod=get_mod(length); long long fin=1; if(num==-1)return 0; if(length==1)return 1; for(int i=length-1;i>=1;--i) for(int j=1;j<=9;++j)fin+=f[i][j]; int head=num/mod; for(int i=1;i<head;++i)fin+=f[length][i]; long long h=g(num,length,head); return fin+h; } int main() { get_table(); long long a,b; cin>>a>>b; long long st=solve(a-1); long long ed=solve(b); cout<<ed-st; return 0; }