HDU-6156 Palindrome Function(数位DP)
一、题目

二、思路
1、这是很明显的数位DP;
2、和以往数位DP不同的是,这里带了个进制进来,而以往做是纯十进制下或者纯二进制下做操作。但是,不管多少进制,原理都是一样的;
3、这里有个小坑,题目中说大于10的数用A、B、C、……、Z表示,那都是骗人的。分解给定数字的每一位数后,得到每一位的就是在给定进制下的该位的权值,压根不需要在数字、字母之间转来转去,纯数字娱乐;
4、比较直观的想法是:
(1)枚举给定范围内的每一个进制;
(2)计算在b进制下的回文数个数,然后即可得出在b进制下的和;
(3)累加上面的所有和,得出最终答案。
5、在4(2)中,利用数位DP计算在b进制下的回文数个数,需要记忆化。如何记忆化,怎么表示状态,这个是本题的关键所在。首先,当前搜索状态在数位中的位置pos,进制b,这个是确定状态的两个依据,不难想到。接下来,先把dp数组的设计放下来,看看dfs函数。既然与回文数有关,那自然,回文序列的起始位置start应该知道,因为前导0是不参与回文计算的。还有一点非常关键:因为要判断一个数是否回文,就必须从端点到中间扫描整个数字序列,而如果要这么做,那我们的记忆化就玩完了,每个数都判断一下,就变成暴力枚举了。所以,要让判断在搜索过程中完成。因此,需要使用一个数组,记录搜索的数字序列。注意,判断这个数字序列是不是回文的一定不是在一个数字所有位搜索完成之后再判断的,否则,就无法记忆化了。因为我们记录了数字序列最高位的起始位置,所以,在搜索过程中,当当前位置<=数字序列中点(start + 1) / 2时,开始做“回文比较”。如果当前已比较的数位对称了,继续比较下一位。当前已比较的数位对称的意思是,形如1213031……的数字序列,假设0所在的位置是这个数字序列的中心点。当当前搜索完省略号“……”前的一个1时,省略号前的31已经和0前面的13形成回文了,就是我所说的数位对称了。当下次使用数字序列3456065……的数字序列再次到达这个状态(注意,我们目前已确定的三个状态标志是,当前搜索状态在数位中的位置pos、进制b、回文序列的起始位置start)时,之后的操作完全和使用之前的序列1213031……到达这个状态后的操作一样。为什么呢?对于第一个数字序列1213031……而言,不管31之后的两位数(因为我们假设了数字序列的中心点是0的所在位置,所以,后面省略号部分其实只有两位,对应前面的12)是什么,肯定能找到21和前面的12对称。同样的道理,对于第二个数字序列3456065……而言,搜索省略号前的5这个位置后,不管后面省略号部分是什么,我总能找到一个43和前面的34对称。所以,在前面的1213031……的序列中,搜索完省略号部分后,当序列3456065……到达这个状态时,直接使用前面记忆化的结果即可,而无需再次向下搜索。这时有个比较疑惑的地方:如果后面省略号部分无法到达43呢,比如说,搜索上界就是345606540。注意,如果有上界限制,我们的程序是不会使用记忆化的结果的。所以,从前面的讨论来看,确定一个状态,还需要一个东西,当前已搜索过的序列是否构成回文串。比如前面的例子,1213031……,从中心点0位置开始,0 == 0,搜索下一位,0后面的3 == 0前面的3,0后面的1 == 0前面的3前面的1……,搜索完这个状态后,当前已搜索过的序列是已经构成回文串的。同样地,如果序列是1213032……,当比较省略号前的2和0前面的3前面的1时,发现不相等,那后面如何,这个序列都不会是回文串了。但是,这也是一种状态,记忆化时需要区分开。所以,说了这么多,可以确定记忆化数组dp的四个状态标志了:①当前搜索状态在数位中的位置pos、②进制b、③回文序列的起始位置start、④搜索到当前位置时,之前搜索过的序列是否已经部分回文。这里的第④个标志特别要注意,已部分回文,不是这样的,11011……(认为这里的11011是回文的)。而是,从这个数字序列的中心位置开始,是否每一位都和其对应位相等。如果是,那么,那就满足④,是已部分回文的。注意,一定要到达中心位置后才能开始判断。
三、注意点
1、这题不需要把前导0作为限制条件加到dfs函数中,有了pos和start就行了。否则,很多本可以记忆化的,加了!lead限制条件后,不能使用记忆化结果,也不能记忆化搜索值。效率大大降低。导致代码在HDU上超时。
2、我用这个测试样例(http://public-1252154746.cosgz.myqcloud.com/acmdata/hdu6156input.txt),加了前导0的限制条件,耗时11s左右。不加该条件,耗时5s左右。在HDUOJ上运行耗时2100ms左右。对应的输出文件:http://public-1252154746.cosgz.myqcloud.com/acmdata/hdu6156output.txt。
四、源代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
LL dp[][][][];//注意,因为最小进制为2,所以,pos最大可能是30(因为x和y最大是1e9),要确保大小足够。
], dn, bit[];
template <class T> inline void read(T &x) {
int t;
bool flag = false;
')) ;
if(t == '-') flag = true, t = getchar();
x = t - ';
+ t - ';
if(flag) x = -x;
}
LL dfs(int pos, int base, int start, bool ispd, bool limit) {
)return ispd;
)return dp[pos][base][start][ispd];
;
LL ans = ;
; i <= top; ++i) {
bit[pos] = i;
)ans += dfs(pos - , , ispd, limit && i == top);
else {
) >> ;
, base, start, ispd, limit && i == top);
, ], limit && i == top);
/**else这里的第4个参数不需要ispd && i == bit[start - pos + 1],因为只要某位和对应位不相等,
那么之后的搜索都会从前面的if中进去。*/
}
}
if(!limit)dp[pos][base][start][ispd] = ans;
return ans;
}
LL solve(LL n, int b) {
dn = ;
) {
digit[++dn] = n % b;
n /= b;
}
return dfs(dn, b, dn, true, true);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
LL L, R, l, r, T, ans;
memset(dp, -, sizeof(dp));
scanf("%lld", &T);
; t <= T; ++t) {
ans = ;
read(L), read(R), read(l), read(r);
for(int b = l; b <= r; ++b) {
LL ans1 = solve(R, b), ans2 = solve(L - , b);
ans += (ans1 - ans2) * b + (R - L + - (ans1 - ans2));
}
printf("Case #%lld: %lld\n", t, ans);
}
;
}
HDU-6156 Palindrome Function(数位DP)的更多相关文章
- HDU 6156 - Palindrome Function [ 数位DP ] | 2017 中国大学生程序设计竞赛 - 网络选拔赛
普通的数位DP计算回文串个数 /* HDU 6156 - Palindrome Function [ 数位DP ] | 2017 中国大学生程序设计竞赛 - 网络选拔赛 2-36进制下回文串个数 */ ...
- HDU 6156 Palindrome Function(数位DP)题解
思路: 数位dp的操作是dfs+记忆化,我们dp开四维:位置,长度,进制,是否回文.然后每次暴搜记录下每个位置的数字是什么,搜到对称轴另一边需要检查是否符合回文. 终于把友谊赛的题目都补完了...没做 ...
- HDU 6156 Palindrome Function
http://acm.hdu.edu.cn/showproblem.php?pid=6156 题意:$f(n,k)$表示判断n在k进制下是否是回文串,如果是,则返回k,如果不是,则返回1.现在要计算$ ...
- HDU 6156 回文 数位DP(2017CCPC)
Palindrome Function Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 256000/256000 K (Java/Ot ...
- 【数位DP】HDU 6156 Palindrome Function
http://acm.hdu.edu.cn/showproblem.php?pid=6156 [AC] #include<bits/stdc++.h> using namespace st ...
- hdu 5898 odd-even number 数位DP
传送门:hdu 5898 odd-even number 思路:数位DP,套着数位DP的模板搞一发就可以了不过要注意前导0的处理,dp[pos][pre][status][ze] pos:当前处理的位 ...
- hdu 5106 Bits Problem(数位dp)
题目链接:hdu 5106 Bits Problem 题目大意:给定n和r,要求算出[0,r)之间全部n-onebit数的和. 解题思路:数位dp,一个ct表示个数,dp表示和,然后就剩下普通的数位d ...
- HDU 2089 - 不要62 - [数位DP][入门题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 Time Limit: 1000/1000 MS (Java/Others) Memory Li ...
- HDU 5179 beautiful number 数位dp
题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5179 bc(中文): http://bestcoder.hdu.edu.cn/contes ...
随机推荐
- Gym 101334F Feel Good
http://codeforces.com/gym/101334 题意:给定一串数,求一个区间,使得该区间的所有数之和乘以该区间内最小的数的乘积最大. 思路:先预处理一下,计算出前缀和. 我们可以把每 ...
- BZOJ 3930 【CQOI2015】 选数
题目链接:选数 这种SB题我都Wa飞了,彻底没救系列- 首先,我们可以发现1,如果我们选了两个不同的数,那么它们的\(\gcd\)不会超过\(r-l+1\).于是,我们可以设一个\(f_i\)表示任取 ...
- JDBC中的事物处理
一项事物是由一个或是多个操作所组成的一个不可分割的工作单元.我们通过提交commit()或是回退rollback()来结束事务的操作. JDBC的事物处理包括三个方面:1:自动提交模式: 2:事务隔离 ...
- mac 下安装 express
express为js的后端框架, 终端 >>> npm install -g express-generator 然后cd到您要创建项目的目录之下,输入 >>> ...
- [java]java String.split()函数的用法分析
转自:http://swiftlet.net/archives/709 一.在java.lang包中有String.split()方法的原型是: public String[] split(Strin ...
- Java Spring-AOP的概述
2017-11-08 19:31:23 AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP ...
- RHEL7.X 安装 11.2.0.4 RAC 问题
随着Linux 7 版本的普及,但Oracle数据库主流版本仍是11gR2,11.2.0.4 是生产安装首选.由于11.2.0.4对Linux 7 的支持不很完美,在Linux 7 上安装会遇到几处问 ...
- Rails 5 Test Prescriptions 第3章Test-Driven Rails
本章,你将扩大你的模型测试,测试整个Rails栈的逻辑(从请求到回复,使用端到端测试). 使用Capybara来帮助写end-to-end 测试. 好的测试风格,包括端到端测试,大量目标明确的单元测试 ...
- HDU1166 敌兵布阵_线段树
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 10046event vs 10053event做了哪些操作
10046 event 告诉我们oracle做了哪些事情,做的怎么样.10053 event 告诉我们oracle优化器怎么想的,再给出成本最低的最终的优化方案,考虑了哪些执行计划拿了哪些统计信息