题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4734

F(x)

Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4389    Accepted Submission(s): 1614

Problem Description
For a decimal number x with n digits (AnAn-1An-2 ... A2A1), we define its weight as F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1
* 1. Now you are given two numbers A and B, please calculate how many
numbers are there between 0 and B, inclusive, whose weight is no more
than F(A).
 
Input
The first line has a number T (T <= 10000) , indicating the number of test cases.
For each test case, there are two numbers A and B (0 <= A,B < 109)
 
Output
For every case,you should output "Case #t: " at first, without quotes. The t is the case number starting from 1. Then output the answer.
 
Sample Input
3
0 100
1 10
5 100
Sample Output
Case #1: 1
Case #2: 2
Case #3: 13
 
Source
 
第一次接触数位DP,本来是奔着记忆化搜去的。结果发现是个数位DP,收获挺大的。
简单的讲一下我的理解:
起根本还是一个记忆化搜索,主要难处理的地方是下一位的取值(一般是从高到低的遍历),比如说,456,第一位你取的是3,你下一位就可以去0~9,但是如果你取的是4,下一位你就只能取0~5了,这也是最巧妙的地方。
然后我找了一下网上的模板,记一下思路,写的很好。
 
  1. int dfs(int i, int s, bool e) {
  2. if(i==-) return s==target_s;
  3. if(!e && ~f[i][s]) return f[i][s];
  4. int res = ;
  5. int u = e?num[i]:;
  6. for(int d = first?:; d <= u; ++d)
  7. res += dfs(i-, new_s(s, d), e&&d==u);
  8. return e?res:f[i][s]=res;
  9. }
 
  1. // pos = 当前处理的位置(一般从高位到低位)
  2. // pre = 上一个位的数字(更高的那一位)
  3. // status = 要达到的状态,如果为1则可以认为找到了答案,到时候用来返回,
  4. //    给计数器+1。
  5. // limit = 是否受限,也即当前处理这位能否随便取值。如567,当前处理6这位,
  6. //    如果前面取的是4,则当前这位可以取0-9。如果前面取的5,那么当前
  7. //    这位就不能随便取,不然会超出这个数的范围,所以如果前面取5的
  8. //    话此时的limit=1,也就是说当前只可以取0-6。
  9. //
  10. // 用DP数组保存这三个状态是因为往后转移的时候会遇到很多重复的情况。
  11. int dfs(int pos,int pre,int status,int limit)
  12. {
  13. //已结搜到尽头,返回"是否找到了答案"这个状态。
  14. if(pos < )
  15. return status;
  16.  
  17. //DP里保存的是完整的,也即不受限的答案,所以如果满足的话,可以直接返回。
  18. if(!limit && DP[pos][pre][status] != -)
  19. return DP[pos][pre][status];
  20.  
  21. int end = limit ? DIG[pos] : ;
  22. int ret = ;
  23.  
  24. //往下搜的状态表示的很巧妙,status用||是因为如果前面找到了答案那么后面
  25. //还有没有答案都无所谓了。而limti用&&是因为只有前面受限、当前受限才能
  26. //推出下一步也受限,比如567,如果是46X的情况,虽然6已经到尽头,但是后面的
  27. //个位仍然可以随便取,因为百位没受限,所以如果个位要受限,那么前面必须是56。
  28. //
  29. //这里用"不要49"一题来做例子。
  30. for(int i = ;i <= end;i ++)
  31. ret += dfs(pos - ,i,status || (pre == && i == ),limit && (i == end));
  32.  
  33. //DP里保存完整的、取到尽头的数据
  34. if(!limit)
  35. DP[pos][pre][status] = ret;
  36.  
  37. return ret;
  38. }
  1. #include<cstdio>
  2. #include<cstring>
  3. #define maxn 16
  4.  
  5. int dp[maxn][];
  6. int d[maxn];
  7. int n;
  8. long long tt;
  9.  
  10. long long dfs(int len,int pre,bool fp)
  11. {
  12. if(pre<) return ;
  13. if(!len) return ;
  14. if(!fp&&dp[len][pre]!=-)return dp[len][pre];//记忆化搜索
  15. int fpmax=fp?d[len]:;
  16. int ret=;
  17. for(int i=; i<=fpmax; i++)
  18. {
  19. ret+= dfs(len-,pre-i*(<<(len-)),fp&&i==fpmax);
  20. }
  21. if(!fp)dp[len][pre]=ret;//记录结果
  22. return ret;
  23. }
  24.  
  25. long long calc(long long a)
  26. {
  27. int len=;
  28. memset(d,,sizeof(d));
  29. while(a)
  30. {
  31. d[++len]=a%;
  32. a/=;
  33. }
  34. return dfs(len,tt,true);
  35. }
  36.  
  37. int get(int x)
  38. {
  39. int tmp=;
  40. int ans=;
  41. while(x)
  42. {
  43. ans+=(x%)*tmp;
  44. x/=;
  45. tmp<<=;
  46. }
  47. return ans;
  48. }
  49.  
  50. int main()
  51. {
  52. //freopen("input.txt","r",stdin);
  53. long long a,b;
  54. int nc;
  55. scanf("%d",&nc);
  56. int d=;
  57. memset(dp,-,sizeof(dp));
  58. while(nc--)
  59. {
  60. scanf("%I64d%I64d",&a,&b);
  61. tt=get(a);
  62. printf("Case #%d: %I64d\n",d++,calc(b));
  63. }
  64. return ;
  65. }

HDU(4734),数位DP的更多相关文章

  1. [hdu 4734]数位dp例题

    通过这个题目更加深入了解到了数位dp在记忆化搜索的过程中就是实现了没有限制条件的n位数的状态复用. #include<bits/stdc++.h> using namespace std; ...

  2. hdu 4734 数位dp

    给一个数A (十进制表示形式为AnAn-1An-2 ... A2A1,定义函数 F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1,给一个B, ...

  3. hdu 4507 数位dp(求和,求平方和)

    http://acm.hdu.edu.cn/showproblem.php?pid=4507 Problem Description 单身! 依旧单身! 吉哥依旧单身! DS级码农吉哥依旧单身! 所以 ...

  4. hdu 4352 数位dp + 状态压缩

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. 2017中国大学生程序设计竞赛 - 网络选拔赛 HDU 6156 数位DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6156 题意:如题. 解法:数位DP,暴力枚举进制之后,就转化成了求L,R区间的回文数的个数,这个直接做 ...

  6. hdu:2089 ( 数位dp入门+模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 数位dp的模板题,统计一个区间内不含62的数字个数和不含4的数字个数,直接拿数位dp的板子敲就行 ...

  7. HDU 4352 XHXJ's LIS HDU(数位DP)

    HDU 4352 XHXJ's LIS HDU 题目大意 给你L到R区间,和一个数字K,然后让你求L到R区间之内满足最长上升子序列长度为K的数字有多少个 solution 简洁明了的题意总是让人无从下 ...

  8. hdu 3709 数位dp

    数位dp,有了进一步的了解,模板也可以优化一下了 题意:找出区间内平衡数的个数,所谓的平衡数,就是以这个数字的某一位为支点,另外两边的数字大小乘以力矩之和相等,即为平衡数例如4139,以3为支点4*2 ...

  9. HDU 2089 数位dp入门

    开始学习数位dp...一道昨天看过代码思想的题今天打了近两个小时..最后还是看了别人的代码找bug...(丢丢) 传说院赛要取消 ? ... 这么菜不出去丢人也好吧~ #include<stdi ...

  10. HDU 2089 数位dp/字符串处理 两种方法

    不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

随机推荐

  1. PostgreSQL 中定义自己需要的数据类型

    PostgreSQL解决某系数据库中的tinyint数据类型问题,创建自己需要的数据类型如下: CREATE DOMAIN tinyint AS smallint CONSTRAINT tinyint ...

  2. G面经prepare: Data Stream Average

    给一个datastream和一个fixed window size, 让我design一个class可以完成add number还有find average in the window. 就是不能用v ...

  3. win7旗舰版梦幻主题补丁~完美你的桌面

    随着VISTA和WIN7的逐渐普及,你是否想拥有一个与众不同的动态桌面呢~ Windows DreamScene属于Ultimate Extras的组件之一,而Ultimate Extras是专门为W ...

  4. HTML中调用servlet的问题(?)

    最近在学习servlet.刚开始时,按照案例一行一行的敲代码.不过,出问题了. hello1.html <!DOCTYPE html> <html> <head> ...

  5. csuoj 1120: 病毒

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1120 1120: 病毒 Time Limit: 3 Sec  Memory Limit: 128 ...

  6. [原创] 在spring 中使用quarts

    1.使用maven加载 quarts 的jar <dependency> <groupId>org.quartz-scheduler</groupId> <a ...

  7. (转)【ASP.NET开发】获取客户端IP地址 via C#

    [ASP.NET开发]获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己 ...

  8. 关于C# winform 快速制作不规则边框的方法

    今天逛博客园突然发现一个帖子写的   快速建立不规则边框的方式 突然发现以前自己用API的方式好傻… 杀鸡焉用牛刀  下边是从网上不断转载的 原帖: 地址:http://www.cnblogs.com ...

  9. 夺命雷公狗---DEDECMS----20dedecms取出栏目页对应的内容

    取出栏目页对应的内容 现在我们的栏目页面是可以完全正常跳转了,那么我们现在需要完成的就是让他的内容全部(电影,连续剧,综艺)分类的显示出来. 我们还是要使用{dede:arclist}标签来取出我们所 ...

  10. 夺命雷公狗---DEDECMS----13dedecms首页的完成

    我们的dedecms搭建起来后直接复制templets的目录复制一份,如下所示: 然后进入templets目录里面,然后再将default里面的东西都给干掉,然后将我们预先准备好的首页放进来,代码如下 ...