题意

求区间[L,R]内满足各位数构成的数列的最长上升子序列长度为K的数的个数。

思路

一开始的思路是枚举数位,最后判断LIS长度。但是这样的话需要全局数组存枚举的各位数字,同时dp数组的区间唯一性也被破坏了(我不知道MYQ10那题怎么被我用这种方法做对的。。。)

看了题解后发现了二进制缩位处理LIS的巧妙方法~~我们用一个长10位的二进制数state表示0~9之前是否出现过,而更新的时候也需要一点技巧:如果我们当前处理到的位数是i,那么我们就找state中不小于i的第一位非0位,把它置0,再把第i位置1。为什么这样处理呢?想想我们更新时的困难,就在于怎样维持state后面1的出现顺序要在前面1的后面,这样最后state中1的个数才表示LIS长度。呐当我们处理i时,对于i后面的1,就不符合出现顺序了,所以需要调整。但是我们发现对于紧接着i的那个1,它可以被i“替换”掉。因为此时以它为结尾和以i为结尾的LIS长度一样(因为是近邻着的下一个1),而它被i“替换”后又不影响了后面1的出现顺序了,把i当成原来的它就行了~

还有一点是,相对于每次询问都初始化dp数组(超时),更好的方法是给dp加一维[11]表示处理的K,这样只需在最开始初始化即可。

代码

[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, end) for (int i = begin; i <= end; i ++)
using namespace std;

typedef unsigned long long LL;
typedef vector <int> VI;

VI num;
LL dp[25][2][1050][11];
LL L, R;
int K;
int getnewstate(int x, int s) {
for (int i = x; i < 10; ++i)
if (s&(1<<i)) return (s^(1<<i))|(1<<x);
return s|(1<<x);
}
int get_dig_num(int state){
int res = 0;
for (int i = 0; i <= 9; i ++){
if (state & (1<<i))
res ++;
}
return res;
}
LL dfs(int pos, bool zero, int state, bool limit){
if (pos == -1){
return (get_dig_num(state) == K);
}
if (!limit && ~dp[pos][zero][state][K]) return dp[pos][zero][state][K];
int end = limit?num[pos]:9;
LL res = 0;
for (int i = 0; i <= end; ++ i){
bool next_zero = (zero && i==0);
res += dfs(pos-1, next_zero, next_zero?0:getnewstate(i, state), limit&&(i==end));
}
return limit?res:dp[pos][zero][state][K]=res;
}
LL solve(LL x){
num.clear();
while(x){
num.push_back(x%10);
x /= 10;
}
LL res = dfs(num.size()-1, 1, 0, true);
return res;
}

int main(){
int t;
MEM(dp, -1);
scanf("%d", &t);
REP(ca, 1, t){
scanf("%I64d %I64d %d", &L, &R, &K);
printf("Case #%d: %I64d\n", ca, solve(R)-solve(L-1));
}
return 0;
}
[/cpp]

HDU 4352 XHXJ's LIS ★(数位DP)的更多相关文章

  1. HDU 4352 XHXJ's LIS 数位dp lis

    目录 题目链接 题解 代码 题目链接 HDU 4352 XHXJ's LIS 题解 对于lis求的过程 对一个数列,都可以用nlogn的方法来的到它的一个可行lis 对这个logn的方法求解lis时用 ...

  2. hdu 4352 XHXJ's LIS 数位dp+状态压缩

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4352 XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others ...

  3. HDU.4352.XHXJ's LIS(数位DP 状压 LIS)

    题目链接 \(Description\) 求\([l,r]\)中有多少个数,满足把这个数的每一位从高位到低位写下来,其LIS长度为\(k\). \(Solution\) 数位DP. 至于怎么求LIS, ...

  4. HDU 4352 XHXJ's LIS (数位DP+LIS+状态压缩)

    题意:给定一个区间,让你求在这个区间里的满足LIS为 k 的数的数量. 析:数位DP,dp[i][j][k] 由于 k 最多是10,所以考虑是用状态压缩,表示 前 i 位,长度为 j,状态为 k的数量 ...

  5. $HDU$ 4352 ${XHXJ}'s LIS$ 数位$dp$

    正解:数位$dp$+状压$dp$ 解题报告: 传送门! 题意大概就是港,给定$[l,r]$,求区间内满足$LIS$长度为$k$的数的数量,其中$LIS$的定义并不要求连续$QwQ$ 思路还算有新意辣$ ...

  6. hdu 4352 XHXJ's LIS 数位DP+最长上升子序列

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

  7. hdu 4352 XHXJ's LIS 数位DP

    数位DP!dp[i][j][k]:第i位数,状态为j,长度为k 代码如下: #include<iostream> #include<stdio.h> #include<a ...

  8. HDU 4352 - XHXJ's LIS - [数位DP][LIS问题]

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

  9. hdu 4352 XHXJ's LIS(数位dp+状压)

    Problem Description #define xhxj (Xin Hang senior sister(学姐)) If you do not know xhxj, then carefull ...

随机推荐

  1. Singleton: this & instance

    public class Singleton{ private static final Singleton instance = new Singleton(); private String na ...

  2. Python 函数的使用小结

    函数的好处:提高代码复用性,简化代码,代码可扩展. 函数只有调用的时候才会被执行. 1.参数: 形参&实参:位置参数,属于必填参数:默认值参数,为非必填参数,没有传值时使用默认值:关键字参数: ...

  3. C# comport 打印图像

    public string GetLogo() { string logo = ""; if (!File.Exists(@"C:\bitmap.bmp")) ...

  4. 聚类之k-means

    1.介绍 k-means算法以k为参数(所期望的簇的个数),把n个对象分成k个簇(单层划分),用质心(数据点的平均值)定义簇的原型.使得簇内具有较高的相似度,而簇间的相似度较低. 通过聚类,我们能够发 ...

  5. JavaScript:学习笔记(9)——Promise对象

    JavaScript:学习笔记(9)——Promise对象 引入Promise Primose是异步编程的一种解决方案,比传统的解决方案回调函数和事件更加合理和强大.如下面为基于回调函数的Ajax操作 ...

  6. C++切割字符串

    std::string text = "2001_1;2005_5;"; std::stringstream ss(text); std::string sub_str; std: ...

  7. 有界、无界队列对ThreadPoolExcutor执行的影响

    本文转载自https://blog.csdn.net/kusedexingfu/article/details/72491864 Java提供了4钟线程池: newCachedThreadPool n ...

  8. vultr VPS安装BBR

    1.安装 wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh chmod +x bbr.s ...

  9. 20145301《Java程序设计》第10周学习总结

    20145301 <Java程序设计>第十周学习总结 教材学习内容总结 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据 计算机网络 路由器和交换机组成了核心的计算机 ...

  10. linux-android(任务处理)

    1.开辟任务内存 2.设置每个任务优先级 ,,