Palindrome Function HDU - 6156 (数位dp)

Palindrome Function

 HDU - 6156 

题意:L到R之间的数x,写成k进制(l<=k<=r)后,如果是回文串,那么f(x,k)=k,否则f(x,k)=1,对f求和。

数位dp

dp[len][cur][sta][k]   长度、当前位置、是否是回文、k进制

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 ll dp[35][35][2][38];
 5 int bit[35];
 6 int num[35];
 7 int L,R,l,r;
 8 
 9 ll dfs(int len,int cur,int sta,int lim,int k){
10     if(cur<0){
11         if(sta) return k;
12         else return 1;
13     }
14     if(!lim&&dp[len][cur][sta][k]!=-1) return dp[len][cur][sta][k];
15     int up=lim?bit[cur]:k-1;
16     ll ans=0;
17     for(int i=0;i<=up;i++){
18         num[cur]=i;
19         if(len==cur&&i==0) ans+=dfs(len-1,cur-1,sta,lim&&i==up,k);
20         else if(sta&&cur<(len+1)/2) ans+=dfs(len,cur-1,sta&&i==num[len-cur],lim&&i==up,k);
21         else ans+=dfs(len,cur-1,sta,lim&&i==up,k);
22     }
23     if(!lim) dp[len][cur][sta][k]=ans;
24     return ans;
25 }
26 ll solve(int x){
27     ll ans=0;
28     for(int i=l;i<=r;i++){
29         int pos=0;
30         int temp=x;
31         while(temp){
32             bit[pos++]=temp%i;
33             temp/=i;
34         }
35         ans+=dfs(pos-1,pos-1,1,1,i);
36     }
37     return ans;
38 }
39 
40 int main(){
41     int t,kase=0;
42     memset(dp,-1,sizeof(dp));
43     scanf("%d",&t);
44     while(t--){
45         scanf("%d%d%d%d",&L,&R,&l,&r);
46         printf("Case #%d: ",++kase);
47         printf("%lld\n",solve(R)-solve(L-1));
48     }
49     return 0;
50 }
View Code

 

posted @ 2017-08-21 16:18  yijiull  阅读(223)  评论(0编辑  收藏  举报