hdu 6156 Palindrome Function(回文数位dp)

题目链接:hdu 6156 Palindrome Function

题意:

给你一个L,R,l,r,问你在[L,R]内在[l,r]进制下有多少数是回文数,然后算一算贡献。

题解:

由于答案和该回文数的最高位有关(因为前导0不算)。

考虑dp[i][j][k],表示在i进制下,当前考虑到第j位,该数字的起始点在第k位。

然后开一个数组记录一下前面的数字,做一下记忆化搜索就行了。

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

 

posted @ 2017-08-19 20:40  bin_gege  阅读(201)  评论(0编辑  收藏  举报