题意:

  前面3/4的英文都是废话。将一个正整数看成字符串,给定一个k,问区间[L,R]中严格的LIS=k的数有多少个?

思路:

  实在没有想到字符0~9最多才10种,况且也符合O(nlogn)求LIS的特点,所以用状态压缩可以解决。

  看到状态压缩的字眼基本就会做了,增加一维来保存当前LIS的状态。由于求LIS时的辅助数组d[i]表示长度为i的LIS最后一个元素,d数组是严格递增的,所以好好利用d数组的特性来设计状态压缩才是关键。压缩的状态0101可以表示:仅有0和2在数组d中,即d[1]=0,d[2]=2的意思。状态的设计方法有多种。

  此题在考虑前导零问题时,逐个枚举位数,可以这样做是因为如果位数超过了1,则最后一个数位若为0是不会对结果构成影响的,因为最后的0都不会被考虑在LIS中。而对于那些个位数为0(或者说后缀0)会对结果产生影响的,最好是不要这样用了(例如spoj Balanced Numbers就不可以)。

 #include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <algorithm>
#include <vector>
#include <iostream>
#define pii pair<int,int>
#define INF 0x7f3f3f3f
#define LL long long
#define ULL unsigned long long
using namespace std;
const double PI = acos(-1.0);
const int N=; LL f[N][<<][], bit[N];
//[位数][状态][k] int insert(int s,bool flag,int pos) //修改状态
{
for(int i=pos; i<=&&flag; i++) //找到第一位>=pos的,抹去
if(s&(<<i))
{
s^=(<<i);
break;
}
return s|(<<pos);
} int gethigh(int s) //获取LIS最大元素,即d[len]。
{
for(int i=; i>=; i--) if(s&(<<i)) return i;
return -;
} LL dfs(int i,int up,int s,int k,bool e)
{
//up为总位数,s为状态,k为仍需一段len=k的串来组成LIS=K的
if(i==) return k==;
if(i<k) return ; //剩下的位数已不够k个,不能组成LIS=k
if(!e && ~f[i][s][k] ) return f[i][s][k]; LL ans=;
int d= i==up? : ; //为了解决前缀0的情况,起始不为0
int u= e? bit[i]: ; int h=gethigh(s); //LIS的最大元素
for( ; d<=u; d++)
{
if(d>h) ans+=dfs(i-,up,insert(s,,d),k-,e&&d==u);
else ans+=dfs(i-,up,insert(s,,d),k,e&&d==u); //LIS长度不变
}
return e? ans: f[i][s][k]=ans;
} LL cal(LL n,int k)
{
if(n==) return ;
int len=;
while(n) //拆数
{
bit[++len]=n%;
n/=;
}
LL ans=;
for(int i=k; i<len; i++) //为了解决前导0问题,逐个枚举
ans+=dfs(i,i,,k,false);
if(len>=k)
ans+=dfs(len,len,,k,true);
return ans;
} int main()
{
//freopen("input.txt","r",stdin);
memset(f, -, sizeof(f));
LL L, R;int t, K, Case=;
cin>>t;
while( t-- )
{
scanf("%lld%lld%d",&L,&R,&K);
printf("Case #%d: %lld\n", ++Case, cal(R,K)-cal(L-,K));
}
return ;
}

AC代码

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

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

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

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

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

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

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

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

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

  5. 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 ...

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

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

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

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

  8. hdu 4352 XHXJ's LIS 数位DP

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

  9. 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 ...

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

    题意 求区间[L,R]内满足各位数构成的数列的最长上升子序列长度为K的数的个数. 思路 一开始的思路是枚举数位,最后判断LIS长度.但是这样的话需要全局数组存枚举的各位数字,同时dp数组的区间唯一性也 ...

随机推荐

  1. UGUI笔记

    Text中的可以单独指定某些文字的颜色,只需将想要变色的文本放在<color=**></color>之间即可,如“吃<color=#ff7a38>橙色物品</ ...

  2. shell程序---编译目录下全部.c或.cpp文件

    今天大波又提起昨天我说的那个程序.这样的,起初我想写一个makefile,每次写完新代码后一键编译目录下所有的.cpp文件. 原因是用makefile的话,每次要把目标文件加紧去才能编译.感觉不方便. ...

  3. (function (window, document, undefined) {})(window, document)什么意思?

    1.IIFE(即时调用的函数表达式),它采取以下表达式: (function (window, document, undefined) { // })(window, document); Java ...

  4. win10彻底关闭自动更新

    第1步 https://jingyan.baidu.com/article/9faa7231e7b78b473c28cbb6.html 第2步 http://www.360doc.com/conten ...

  5. unity打包选项编辑器扩展

    using UnityEngine; using UnityEditor; using UnityEditor.Callbacks; using System.IO; public class Pos ...

  6. PHP 数字补零 固定位数补0

    在处理订单编号的时候,需要固定位数的数字,比如需要固定四位数格式: 1->0001 56->0056 288->0288 1992->1992 可以使用php内置函数str_p ...

  7. IT兄弟连 Java语法教程 编译Java程序

    编写好Java程序的源代码后,接下来就应该编译该Java源文件来生成字节码文件了. 编译Java程序需要使用JDK中提供的javac命令,因为已经把javac命令所在的路径添加到了系统的Path环境变 ...

  8. PJzhang:kali linux安装网易云音乐、Visual Studio Code、skype

    猫宁!!! 参考链接:https://blog.csdn.net/cloudatlasm/article/details/79183583 https://code.visualstudio.com/ ...

  9. thinkphp5实现mysql数据库还原

    数据库还原其实就是从.sql文件中读取一行一行的命令,然后执行 需要配置数据库文件database.php,数据库名,主机名,用户名,密码这里就不说了,这里说的要配置数据库连接参数 'params' ...

  10. 《SQL 进阶教程》 case:练习题1-1-1 多列数据的最大值

    select name, case when case when x > y then x else y end < z then z else case when x < y th ...