1. 程式人生 > >hdu 6156 Palindrome Function(回文數位dp)

hdu 6156 Palindrome Function(回文數位dp)

fin while rom target col bsp sca mes spl

題目鏈接: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

hdu 6156 Palindrome Function(回文數位dp)