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 }

时间: 2024-12-05 21:58:38

hdu 6156 Palindrome Function(回文数位dp)的相关文章

HDU 6156 Palindrome Function 数位DP

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6156 题目描述: 求L~R所有的数的l~r进制的f(x), f(x) = 当前进制 如果回文串, f(x) = 1 其他情况 解题思路: 数位DP, 统计个数 , 需要作出改变的就是进制和回文 代码: #include <iostream> #include <cstdio> #include <string> #include <vector> #inclu

HDU 6156 回文 数位DP(2017CCPC)

Palindrome Function Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Others)Total Submission(s): 559    Accepted Submission(s): 299 Problem Description As we all know,a palindrome number is the number which reads the same

HDU 1513 Palindrome 求回文串

这个题是走弯路了,刚开始自己DP出了方程,无限MLE,唉 if(s1[i]==s1[j]) dp[i][j]=dp[i+1][j-1]; else dp[i][j]=min(dp[i][j-1],dp[i+1][j]) +1; 后来百度了一下,这个原来是个经典回文串问题,即先将串置反,然后求LCS........ 然后就是这题卡时间卡的特别厉害,多用了一次strlen就TLE AC: #include<cstdio> #include<string> #include<str

hdu 6156 Palindrome Function

数据好像极限,按理来说二分是可以过得,就是被卡主 #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<cmath> #include<set> #

【数位DP】HDU 6156 Palindrome Function

http://acm.hdu.edu.cn/showproblem.php?pid=6156 [AC] 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll mod=1e9+7; 5 int num[50]; 6 int L,R,l,r; 7 ll query(int x,int k) 8 { 9 if(x==0) return 0; 10 int cnt=0; 11 int cp

hdu4632 Palindrome subsequence 回文子序列个数 区间dp

Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/Others)Total Submission(s): 4513    Accepted Submission(s): 1935 Problem Description In mathematics, a subsequence is a sequence that can be derived f

hdu 6599 I Love Palindrome String 回文自动机

hdu 6599 I Love Palindrome String 回文自动机 当个回文自动机的模板 题意 给一个串S,求长度为i的"特殊回文串"个数,"特殊回文串"要求是回文串,并且自己的一半也是回文串. 思路 求回文串个数相关,优先考虑使用回文自动机,"特殊回文串"要求是回文串,并且自己的一半也是回文串,显然就是fail树扒出来dfs搞一下,记录dfs路径上有没有长度一半的回文串即可. PS:因为fail指针的意义是最长后缀回文,反过来路径显

HDU 4745 最长回文子序列

题目大意 两只青蛙朝不同方向条,每次都到达值相同的位置,不能重复到达自己到过的地方,且不能飞跃已到过的地方 我们可以理解为这两只青蛙分别把整个序列遍历了一遍,依次走过所有的点,找到最多相同的点的个数,因为朝不同方向,且形成环,所以可以把数组扩大两倍,写两组一样的数组 每次跳完得到的必然可以理解为是一个回文子序列 这里有个例外,就是在已形成的回文子序列下 要是还有多出的点是可以加一的,因为可以令两只青蛙同时在这一点出发再去遍历回文串 DP过程 //DP过程是先从前后两个数距离范围最小的1开始,不断

LeetCode Valid Palindrome 有效回文(字符串)

1 class Solution { 2 public: 3 bool isPalindrome(string s) { 4 if(s=="") return true; 5 if(s.length()==1) return true; //单个字符,对称 6 char *p,*q; 7 p=&s[0]; //p指向开头 8 q=&s[s.length()-1]; //q指向末尾 9 while(p!=q){ 10 //测试字符串里是否有字母或数字,若没有,则立刻返回