代码+题解:

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

    题目 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 分析 关键是如何想到用 ...

  2. 开发进阶:Dotnet Core多路径异步终止

    今天用一个简单例子说说异步的多路径终止.我尽可能写得容易理解吧,但今天的内容需要有一定的编程能力.   今天这个话题,来自于最近对gRPC的一些技术研究. 话题本身跟gRPC没有太大关系.应用中,我用 ...

  3. kafka(三)原理剖析

    一.生产者消息分区机制原理剖析 在使用Kafka 生产和消费消息的时候,肯定是希望能够将数据均匀地分配到所有服务器上.比如很多公司使用 Kafka 收集应用服务器的日志数据,这种数据都是很多的,特别是 ...

  4. 小白的经典CNN复现(二):LeNet-5

    小白的经典CNN复现(二):LeNet-5 各位看官大人久等啦!我胡汉三又回来辣(不是 最近因为到期末考试周,再加上老板临时给安排了个任务,其实LeNet-5的复现工作早都搞定了,结果没时间写这个博客 ...

  5. RVA与FOA的转换

    主要取决于文件对齐与内存对齐的值

  6. 日志采集技术分析 Inode Inotify

    日志采集技术分析[阿里] - 新手学习导向 - 中国红客联盟 - Powered by HUC http://www.cnhonkerarmy.com/thread-236973-1-1.html

  7. 1 flume快速入门——十分钟学会flume

    flume ## 1.1 Flume定义 Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统.Flume基于流式架构,灵活简单. 大数据框架大致分为3类: ...

  8. 新型赌博黑产攻击肆虐网吧: LOL博彩引流+棋牌盗号

    https://mp.weixin.qq.com/s/BxnovV6jKqPkYfHEzjd_FA 新型赌博黑产攻击肆虐网吧: LOL博彩引流+棋牌盗号 看雪学院 2019-04-21

  9. 键相同,比较两个map中的值是否相同

    获取.排序.比较两个Map中相同key对应value值 /** * * @param hashMap 原数据 * @param hashMap2 需要比较的数据 * @return */ privat ...

  10. LOJ10064黑暗城堡

    题目描述你知道黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度. 城堡是树形的并且满足下面的条件: 设 Di​ 为如果所有的通道都被修建,第 i 号房间与第 1 号房间的最短路径长 ...