一、题目

  

二、思路

  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)的更多相关文章

  1. HDU 6156 - Palindrome Function [ 数位DP ] | 2017 中国大学生程序设计竞赛 - 网络选拔赛

    普通的数位DP计算回文串个数 /* HDU 6156 - Palindrome Function [ 数位DP ] | 2017 中国大学生程序设计竞赛 - 网络选拔赛 2-36进制下回文串个数 */ ...

  2. HDU 6156 Palindrome Function(数位DP)题解

    思路: 数位dp的操作是dfs+记忆化,我们dp开四维:位置,长度,进制,是否回文.然后每次暴搜记录下每个位置的数字是什么,搜到对称轴另一边需要检查是否符合回文. 终于把友谊赛的题目都补完了...没做 ...

  3. HDU 6156 Palindrome Function

    http://acm.hdu.edu.cn/showproblem.php?pid=6156 题意:$f(n,k)$表示判断n在k进制下是否是回文串,如果是,则返回k,如果不是,则返回1.现在要计算$ ...

  4. HDU 6156 回文 数位DP(2017CCPC)

    Palindrome Function Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 256000/256000 K (Java/Ot ...

  5. 【数位DP】HDU 6156 Palindrome Function

    http://acm.hdu.edu.cn/showproblem.php?pid=6156 [AC] #include<bits/stdc++.h> using namespace st ...

  6. hdu 5898 odd-even number 数位DP

    传送门:hdu 5898 odd-even number 思路:数位DP,套着数位DP的模板搞一发就可以了不过要注意前导0的处理,dp[pos][pre][status][ze] pos:当前处理的位 ...

  7. hdu 5106 Bits Problem(数位dp)

    题目链接:hdu 5106 Bits Problem 题目大意:给定n和r,要求算出[0,r)之间全部n-onebit数的和. 解题思路:数位dp,一个ct表示个数,dp表示和,然后就剩下普通的数位d ...

  8. HDU 2089 - 不要62 - [数位DP][入门题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 Time Limit: 1000/1000 MS (Java/Others) Memory Li ...

  9. HDU 5179 beautiful number 数位dp

    题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5179 bc(中文): http://bestcoder.hdu.edu.cn/contes ...

随机推荐

  1. Notepad++ 管理工程--转载

    http://blog.csdn.net/cashey1991/article/details/7001385 @1.首先从下面这个菜单打开工程panel @2.在工程panel的“Workspace ...

  2. python 字符串的反转

    def string_reverse(str1): rstr1 = '' index = len(str1) : rstr1 += str1[ index - ] index = index - re ...

  3. 一些自己常用的cdn

    1.vue <script src="http://cdn.bootcss.com/vue/1.0.28-csp/vue.js"></script> < ...

  4. thinkphp5中的配置如何使用

    thinkphp5中的配置如何使用 一.总结 一句话总结:先加载配置,然后读取配置即可 加载配置 读取配置 Config::load(APP_PATH.'fry_config.php');\\加载配置 ...

  5. Linux编写一个C程序HelloWorld

    环境 需要文本编辑器和编译器,文本编辑器用linux(我用的centos7)自带的vi,编译器用gcc(GNU C Compiler/GNU Compiler Collection) 安装gcc,查看 ...

  6. Psping 实例

    PsPing v2.1 https://docs.microsoft.com/zh-cn/sysinternals/downloads/psping 2016/06/29 4 分钟阅读时长 By Ma ...

  7. 联想A390T刷机ROOT教程

    一.联想A390T手动进入Recovery的方法: [步骤一]首先,将你的A390T手机关机,关机状态下,先按住电源键2秒,不要松开,再同时按下音量加.音量减两个键,此时,3个键一直按住不要放开,几秒 ...

  8. js遍历json的key和value

    遍历json对象: 无规律: <script> var json = [{dd:'SB',AA:'东东',re1:123},{cccc:'dd',lk:'1qw'}]; for(var i ...

  9. xml生成javabean(zhuan)

    package com.dom4j; import java.io.File;import java.io.FileWriter;import java.io.IOException;import j ...

  10. Alpha阶段敏捷冲刺---Day1

    一.Daily Scrum Meeting照片 二.今天冲刺情况反馈 1.昨天已完成的工作    昨天我们组全体成员在五社区五号楼719召开了紧急会议,在会议上我们梳理了编写这个程序的所有流程,并且根 ...