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 }