light oj 1205 - Palindromic Numbers 数位DP
思路:搜索的时候是从高位到低位,所以一旦遇到非0数字,也就确定了数的长度,这样就知道回文串的中心点。
代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<vector> 6 #include<cstring> 7 #define ll long long 8 using namespace std; 9 ll dp[20][20][2]; 10 int bit[20],num[20]; 11 ll dfs(int pos,int m,int s,bool f) 12 { 13 if(!pos) return 1; 14 if(!f&&dp[pos][m][s]!=-1) return dp[pos][m][s]; 15 ll ans=0; 16 int e=f?bit[pos]:9; 17 for(int i=0;i<=e;i++){ 18 if(!s){ 19 num[pos]=i; 20 ans+=dfs(pos-1,m-!i,s||i,f&&i==e); 21 } 22 else{ 23 int t=(m+1)>>1; 24 bool flag=m&1?pos<t:pos<=t; 25 if(flag){ 26 if(num[m+1-pos]==i) 27 ans+=dfs(pos-1,m,s,f&&i==e); 28 } 29 else{ 30 num[pos]=i; 31 ans+=dfs(pos-1,m,s,f&&i==e); 32 } 33 } 34 } 35 if(!f) dp[pos][m][s]=ans; 36 return ans; 37 } 38 ll cal(ll n) 39 { 40 int m=0; 41 while(n){ 42 bit[++m]=n%10; 43 n/=10; 44 } 45 return dfs(m,m,0,1); 46 } 47 int main() 48 { 49 int t,ca=0; 50 ll a,b; 51 memset(dp,-1,sizeof(dp)); 52 scanf("%d",&t); 53 while(t--){ 54 scanf("%lld%lld",&a,&b); 55 if(a>b) swap(a,b); 56 printf("Case %d: %lld\n",++ca,cal(b)-cal(a-1)); 57 } 58 return 0; 59 }