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 }
View Code

 

 

 

posted @ 2013-09-13 21:25  _随心所欲_  阅读(461)  评论(0编辑  收藏  举报