代码+题解:

  1. 1 //题意:
  2. 2 //输出在区间[li,ri]中有多少个数是满足这个要求的:这个数的最长递增序列长度等于k
  3. 3 //注意是最长序列,可不是子串。子序列是不用紧挨着的
  4. 4 //
  5. 5 //题解:
  6. 6 //很明显前面最长递增序列的长度会影响到后面判断,而且还要注意我们要采用哪种求最长递增序列的方式(一共有两种,
  7. 7 //一种复杂度为nlog(n),另一种是n^2),这里我才采用的是nlog(n)的。
  8. 8 //
  9. 9 //算法思想:
  10. 10 //定义d[k]:
  11. 11 //长度为k的上升子序列的最末元素,若有多个长度为k的上升子序列,则记录最小的那个最末元素。
  12. 12 //定义a[]:a数组放置的是我们要处理的元素
  13. 13 //首先len = 1,d[1] = a[1],然后对a[i]:若a[i]>d[len],那么len++,d[len] = a[i];
  14. 14 //否则,我们要从d[1]到d[len-1]中找到一个j,满足d[j-1]<a[i]<d[j],则根据D的定义,我们需要更新长度为j的上升子序列的最末元素(使之为最小的)
  15. 15 //即 d[j] = a[i];最终答案就是len
  16. 16 //
  17. 17 //代码:
  18. 18 //d[1] = a[1];
  19. 19 //len=1;
  20. 20 //for(i=2; i<=p; ++i)
  21. 21 //{
  22. 22 // if(a[i]>d[len])
  23. 23 // d[++len]=a[i];
  24. 24 // else
  25. 25 // {
  26. 26 // int pos=binary_search(i); // 如果用STL: pos=lower_bound(d,d+len,a[i])-d;
  27. 27 // d[pos] = a[i];
  28. 28 // }
  29. 29 // printf("%d\n",len);
  30. 30 //}
  31. 31 //
  32. 32 //结果:
  33. 33 //这个d数组里面放置得结果可能不是正确最长递增序列对应的一个序列,它的长度是可以保证是正确的,但是序列本身不一定
  34. 34 //
  35. 35 //回归原题:
  36. 36 //本体就采用这一种方法来获取最长递增序列,每一个位置都对应一个最长递增序列(虽然这个序列本身不一定对,但是它可以
  37. 37 //当作一个状态)
  38. 38 //比如一个递增序列为0 1 3 4那么就把它压缩成二进制的每一位,即2^0+2^1+2^3+2^4,这个结果就是我们的状态,这个样子
  39. 39 //我们就把0、1、2、3、4、5、6、7、8、9这些状态压缩成了一个值。
  40. 40 //然后就写出来了。。。。
  41. 41
  42. 42 #include<stdio.h>
  43. 43 #include<string.h>
  44. 44 #include<algorithm>
  45. 45 #include<iostream>
  46. 46 using namespace std;
  47. 47 const int maxn=20;
  48. 48 const int N=1<<10;
  49. 49 typedef long long ll;
  50. 50 ll v[maxn],dp[maxn][N][20],w[15],k;
  51. 51 ll update(ll x,ll y) //更新我们压缩的状态
  52. 52 {
  53. 53 for(ll i=x; i<10; ++i)
  54. 54 {
  55. 55 if(y&(1<<i)) return ((y^(1<<i))|(1<<x));
  56. 56 }
  57. 57 return y|(1<<x);
  58. 58 }
  59. 59 ll get_num(ll x)
  60. 60 {
  61. 61 ll ans=0;
  62. 62 while(x)
  63. 63 {
  64. 64 if(x&1) ans++;
  65. 65 x>>=1;
  66. 66 }
  67. 67 return ans;
  68. 68 }
  69. 69 ll dfs(ll pos,ll sta,bool limit,bool lead)
  70. 70 {
  71. 71 if(get_num(sta)>k) return 0;
  72. 72 if(pos==-1)
  73. 73 {
  74. 74 if(get_num(sta)==k)
  75. 75 return 1;
  76. 76 else return 0;
  77. 77 }
  78. 78 if(!limit && dp[pos][sta][k]!=-1) return dp[pos][sta][k];
  79. 79 ll up=limit?v[pos]:9;
  80. 80 ll tmp=0;
  81. 81 for(ll i=0; i<=up; ++i)
  82. 82 {
  83. 83 //这一行可以代替下面的
  84. 84 //tmp+=dfs(pos-1,(lead&&i==0)?0:update(i,sta),limit && i==v[pos],lead&&(i==0));
  85. 85 //像下面这样写也对
  86. 86 if(lead && i==0)
  87. 87 {
  88. 88 tmp+=dfs(pos-1,0,limit && i==v[pos],1);
  89. 89
  90. 90 }
  91. 91 else
  92. 92 {
  93. 93
  94. 94 tmp+=dfs(pos-1,update(i,sta),limit && i==v[pos],0);
  95. 95
  96. 96 }
  97. 97 }
  98. 98 if(!limit) dp[pos][sta][k]=tmp;
  99. 99 //只有上界为9的时候才会往dp数组里面存,因为这样能节省更多的时间
  100. 100 return tmp;
  101. 101 }
  102. 102 ll solve(ll ans)
  103. 103 {
  104. 104 ll pos=0;
  105. 105 while(ans)
  106. 106 {
  107. 107 v[pos++]=ans%10;
  108. 108 ans/=10;
  109. 109 }
  110. 110 return dfs(pos-1,0,true,1);
  111. 111 }
  112. 112 int main()
  113. 113 {
  114. 114 ll t,l,r,p=0;
  115. 115 memset(w,0,sizeof(w));
  116. 116 scanf("%I64d",&t);
  117. 117 memset(dp,-1,sizeof(dp));
  118. 118 while(t--)
  119. 119 {
  120. 120 scanf("%I64d%I64d%I64d",&l,&r,&k);
  121. 121 printf("Case #%I64d: %I64d\n",++p,solve(r)-solve(l-1));
  122. 122 }
  123. 123 return 0;
  124. 124 }

XHXJ's LIS HDU - 4352 最长递增序列&数位dp的更多相关文章

  1. hdu 1087 最长上升序列和 dp

    Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

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

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

  3. POJ 2533 Longest Ordered Subsequence 最长递增序列

      Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequenc ...

  4. uva103(最长递增序列,dag上的最长路)

    题目的意思是给定k个盒子,每个盒子的维度有n dimension 问最多有多少个盒子能够依次嵌套 但是这个嵌套的规则有点特殊,两个盒子,D = (d1,d2,...dn) ,E = (e1,e2... ...

  5. [LeetCode] Number of Longest Increasing Subsequence 最长递增序列的个数

    Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...

  6. Leetcode 674.最长递增序列

    最长递增序列 给定一个未经排序的整数数组,找到最长且连续的的递增序列. 示例 1: 输入: [1,3,5,4,7] 输出: 3 解释: 最长连续递增序列是 [1,3,5], 长度为3. 尽管 [1,3 ...

  7. [LeetCode] 673. Number of Longest Increasing Subsequence 最长递增序列的个数

    Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...

  8. 九度OJ 1262:Sequence Construction puzzles(I)_构造全递增序列 (DP)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:118 解决:54 题目描述: 给定一个整数序列,请问如何去掉最少的元素使得原序列变成一个全递增的序列. 输入: 输入的第一行包括一个整数N( ...

  9. HDU 4352 XHXJ's LIS HDU 题解

    题目 #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then carefully reading the ent ...

随机推荐

  1. MongoDB导出导入功能

    导出脚本: mongo_export.sh !#/bin/bash mongoexport -h x.x.x.x  --port 27017 -d database -c collection  -q ...

  2. 两万字长文总结,梳理 Java 入门进阶那些事

    大家好,我是程序员小跃,一名在职场已经写了6年程序的老程序员,从一开始的菊厂 Android 开发到现在某游戏公司的Java后端架构,对Java还是相对了解的挺多. 大概是半年前吧,在知乎上有个知友私 ...

  3. kubernets之ReplicaSet

    一   介绍RS 1.1   RS与RC在功能上基本上是一摸一样的,因为两者的功能都是用来管控集群内部的pod,并且 两者都具备模版,副本数量以及标签选择器等三要素,区别点在于,RS拥有着更为强大的标 ...

  4. 单片机—Arduino UNO-R3—学习笔记001

    连接方法 下载Arduino软件 安装完成打开如图所示 观察右下角的连接接口"Arduino Uno在COM(X)" 在工具-->端口-->选择之前查看的端口 即为连接 ...

  5. Vue MVVM模型原理

    最近反思了下自己,觉得自己很急躁,学技术总是觉得能用就行了,其实这样很不好,总是这样,就永远只能当用轮子的人.好了,废话不多说,转入正题: 要理解MVVM的原理,首先要理解它是什么,怎么运作起来的: ...

  6. java进阶(33)--IO流

    一.IO流概念:1.基本概念2.IO流分类3.java.io流的四大家族4.流的close和flush方法5.java.id下常用的16个流 二.FileInputStream字节输入流1.FileI ...

  7. SQLHelper ------ python实现

    SQLHelper ------ python实现 1.第一种: import pymysql import threading from DBUtils.PooledDB import Pooled ...

  8. 浅析Linux进程空间布局

    一.进程空间分布概述 对于一个进程,其空间分布如下图所示: 1.参数说明 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码. 初始化过的数据(Data):在程序运行初已经对变量进行初 ...

  9. Codeforces #698 (Div. 2) E. Nezzar and Binary String 题解

    中文题意: 给你两个长度为 \(n\) 的01串 \(s,f,\)有 \(q\) 次询问. 每次询问有区间 \([\ l,r\ ]\) ,如果 \([\ l,r\ ]\) 同时包含\(0\)和\(1\ ...

  10. loj2587铁人两项

    无向图,图中选出定点三元组(a,b,c),a->b->c的路径没有重复边.问方案有多少? -------------------------------------------- 首先求出 ...