题目描述:

求给定区间中的回文数有多少个?

首先明确一点,如果一个数是回文数,那么给这个数两边加上相同的数,那么这个数还是回文数。

根据这点就可以进行递推了,p[start][end]=9*p[start+1][end-1](start位不为0)+p[start-1][end](start位为0);

在设计dfs的时候,由于回文数是对称的,所以只需要一个变量cur(cur>mid)就可以表示从cur到cur对称的位置的回文数的个数;

d[start][cur]表示从start位到cur位时,回文数的个数。

这句话隐含的意思是最高位为start,枚举到第cur位,由于是回文数,所以当cur>mid时,[cur,start]位确定,他们的对称位[1,start+1-cur]也就确定了,

还需枚举[cur,mid]这些位;当cur=mid时任意枚举,对回文数没有影响,当cur<mid时,由于是回文数,已经确定了,不需枚举。

再增加一维表示当前枚举的数字是不是回文数(([start,cur]位是否为回文数);

d[start][cur][state]表示从start位到cur位时,状态为state时回文数的个数。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <vector>
  5. #include <algorithm>
  6. using namespace std;
  7. #define LL long long
  8. LL n,m;
  9. LL d[][][];
  10. int digit[];
  11. int num[];
  12. LL dfs(int start,int cur,int Zero,int state,bool fp)
  13. {
  14. if(!cur)
  15. return state;
  16. if(!fp && d[start][cur][state]!= -)
  17. return d[start][cur][state];
  18. LL ret = ;int fpmax = fp ? digit[cur] : ;
  19. for(int i=;i<=fpmax;i++)
  20. {
  21. if( (Zero &&(i==)) )
  22. ret+=dfs(start-,cur-,Zero&&(i==),state, fp&& i==fpmax);
  23. else
  24. {
  25. num[cur]=i;
  26. if( (start & )== )
  27. {
  28. int mid=((start+)>>);
  29. if(cur== mid)
  30. {
  31. ret+=dfs(start,cur-,,state,fp&& i==fpmax);
  32. }
  33. else if(cur < mid )
  34. {
  35. ret+=dfs(start,cur-,,state&& (num[mid*-cur]==i),fp&& i==fpmax);
  36. }
  37. else if(cur>mid)
  38. {
  39. ret+=dfs(start,cur-,,state,fp&& i==fpmax);
  40. }
  41. }
  42. else
  43. {
  44. int mid=(start>>)+;
  45. if(cur<mid)
  46. {
  47. ret+=dfs(start,cur-,,state&& (num[start+-cur]==i),fp&& i==fpmax);
  48. }
  49. else
  50. {
  51. ret+=dfs(start,cur-,,state,fp&& i==fpmax);
  52. }
  53. }
  54. }
  55. }
  56. if(!fp) //如果是前缀,当前得到的ret的值,就不能代表dp[len][state]的值
  57. d[start][cur][state] = ret;
  58. return ret;
  59. }
  60.  
  61. LL f(LL n)
  62. {
  63. int len = ;
  64. if(n==-)
  65. return ;
  66. while(n)
  67. {
  68. digit[++len] = n % ;
  69. n /= ;
  70. }
  71. LL answer=dfs(len,len,,,true);
  72. return answer;
  73. }
  74. void init()
  75. {
  76. memset(d,-,sizeof(d));
  77. }
  78. int main()
  79. {
  80. // freopen("test.txt","r",stdin);
  81. int t;
  82. scanf("%d",&t);
  83. int Case=;
  84. while(t--)
  85. {
  86. scanf("%lld%lld",&n,&m);
  87. init();
  88. if(n>m)
  89. swap(n,m);
  90. printf("Case %d: %lld\n",++Case,f(m)-f(n-));
  91. }
  92. return ;
  93. }

light oj 1205(数位DP)的更多相关文章

  1. light oj 1032(数位DP)

    求一段区间中,每个十进制数所对应的二进制数中连续的1的个数之和. 设dp[i][0]代表长度为i的二进制数,首位为0,所含有的连续的1的个数之和. dp[i][1]代表长度为i的二进制数,首位为1,所 ...

  2. light oj 1068 数位dp

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> ...

  3. light oj 1205 - Palindromic Numbers 数位DP

    思路:搜索的时候是从高位到低位,所以一旦遇到非0数字,也就确定了数的长度,这样就知道回文串的中心点. 代码如下: #include<iostream> #include<cstdio ...

  4. Light oj 1030 概率DP

    D - Discovering Gold Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:32768 ...

  5. lightoj 1205 数位dp

    1205 - Palindromic Numbers    PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 3 ...

  6. light oj 1422 区间dp

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> ...

  7. light oj 1084 线性dp

    #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> ...

  8. light 1205 - Palindromic Numbers(数位dp)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1205 题解:这题作为一个数位dp,是需要咚咚脑子想想的.这个数位dp方程可能不 ...

  9. light oj 1068 - Investigation 数位DP

    思路:典型的数位DP!!! dp[i][j][k]:第i位,对mod取余为j,数字和对mod取余为k. 注意:由于32位数字和小于95,所以当k>=95时,结果肯定为0. 这样数组就可以开小点, ...

随机推荐

  1. POJ 2002 几何+hash

    题目大意: 给定1000个点,寻找有多少组四点对能组成正方形 这里的题目跟上一道做的找平行四边形类似但想法却又不相同的方法 这里找任意2个点形成的一条边,那么可以根据这两个点,找到能和他们组成正方形剩 ...

  2. 理解流方式上传和form表单上传

    流方式上传: $post_input = 'php://input'; $save_path = dirname( __FILE__ ); $postdata = file_get_contents( ...

  3. Eventquery.vbs

    https://docs.microsoft.com/en-us/previous-versions/orphan-topics/ws.10/cc772995(v=ws.10)

  4. UESTC 1087 【二分查找】

    问了某明==shit 中文题意不解释. 因为数据的范围是1e9以内的所以我们可以通过二分的方法枚举可能的中位数. 用二分法每次判断某一数字比中位数大还是比中位数小. 判断方法是,枚举以第n个数为起点的 ...

  5. powerDigner使用

    PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据库建模发展,而PowerDesign ...

  6. oracle coherence介绍及使用

    网上除了官方用户指南,关于Coherence的介绍文章资料很少,因此总结出此文,从原理到快速指南和基本最佳实践,希望对需要的人提供一个参考. 1 Coherence 概述 1.1 Coherence是 ...

  7. RHEL 启动系统及故障排除

    一:Linux的启动过程: 开机加电自检->MBR引导(boot loader占446字节,分区列表64字节,magic占2字节)-->grub菜单(MBR是grub的第一个字段,第二个字 ...

  8. Android双列滑动表格(双表头不动)

    ※效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGluZ2xvbmd4aW4yNA==/font/5a6L5L2T/fontsize/400/fil ...

  9. Exception from container-launch: org.apache.hadoop.util.Shell$ExitCodeException

    使用MapReduce编写的中文分词程序出现了 Exception from container-launch: org.apache.hadoop.util.Shell$ExitCodeExcept ...

  10. 阿里云 oss 小文件上传进度显示

    对阿里云OSS上传小文件时的进度,想过两个方法:一是.通过多线程监測Inputstream剩余的字节数来计算,可是由于Inputstream在两个线程中共用,假设上传线程将Inputstream关闭, ...