题解 最长上升序列2 — LIS2
最长上升序列2 — LIS2
Description
已知一个 1 ∼ N 的排列的最长上升子序列长度为 K ,求合法的排列个数。
Input
输入一行二个整数 N , K ( K ≤ N ≤ 15) 。
Output
输出一行一个整数,描述合法的排列个数。
Sample Input
15 8
Sample Output
37558353900
解析
这题...额...还是得打记搜.
首先,让我们回顾一下求最长上升序列的二分的方法吧(神犇可自动跳过当然神犇可能不需要看本蒟蒻的题解)
我们维护一个类似于栈的数组$q$(其实是序列但为了方便懒得打字后面就称作栈吧)
令$q[i]$表示长度为$i$的序列的最后一个元素,
那么,从$1$~$n$枚举,每次在$q$中寻找第一个大于$a[i]$(即权值)的元素,
再用$a[i]$去更新它,并且它的下标就是以$a[i]$结尾的最长上升序列.
最后,再从$1$~$n$扫一遍,取最大值就行了.
那么,回到这题,
我们在搜索时,保留三个信息$s$,\(t\),\(len\),
$s$表示栈中的信息,$t$表示每个数字是否被选中,$len$表示最长上升子序列,
并且,\(s\),$t$都可以状压,
对于$s$,用一个三进制数表示,0表示未考虑,1表示已被更新,2表示目前在栈中,
对于$t$,用二进制数表示就行了,0表示已选,1表示未选.
那么,初始状态就是(0,(1<<\(n\))-1,0),
接下来,考虑状态转移.
枚举$t$中的每个二进制位为1的数,并更新$q$(就是那个栈),
再搜索下一层,
当$t$等于0,即每个数都被选时,如果$len$等于$k$,就返回1,
如果当前的$s$已经被搜过,就直接返回就行了.
还有什么不明白的就看代码吧:
#include <cstdio>
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
inline int read(){
int sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return f*sum;
}
int n,m;
ll f[15000001];
int a[1<<15]/*状态对应的数字*/,p[16]/*3的指数*/;
int q[10001]/*栈*/;
ll dfs(int s/*栈的状态*/,int t/*数字被选的状态*/,int len/*最长上升序列的长度*/){
if(!t) return len==m;//每个数都被选了
if(f[s]!=-1) return f[s];
f[s]=0;int pos=0,tt=t;
while(t){
int k=t&-t;t^=k;//用lowbit寻找二进制位为1的状态
while(pos<len&&q[pos+1]<a[k]) pos++;
int l=q[pos+1];
q[pos+1]=a[k];//寻找并更新栈
f[s]+=dfs(s+2*p[a[k]]-p[l],tt^k,len+(pos==len));
q[pos+1]=l;//回溯
}
return f[s];
}
int main(){
n=read();m=read();//m就是k,不过写习惯了[滑稽]
for(int i=1;i<=n;i++){
a[1<<(i-1)]=i;//预处理,状态所代表的数
p[i]= i==1? 1:p[i-1]*3;//三的指数
}
memset(f,0xff,sizeof(f));
printf("%lld\n",dfs(0,(1<<n)-1,0));
return 0;
}
题解 最长上升序列2 — LIS2的更多相关文章
- CJOJ 【DP合集】最长上升序列2 — LIS2
题面 已知一个 1 ∼ N 的排列的最长上升子序列长度为 K ,求合法的排列个数. 好题(除了我想不出来我应该找不到缺点), 想一想最长上升子序列的二分做法, 接在序列后面或者替换. 所以对于每一个位 ...
- POJ 2533 Longest Ordered Subsequence 最长递增序列
Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequenc ...
- P1091 合唱队形 DP 最长升序列维护
题目描述 NN位同学站成一排,音乐老师要请其中的(N-KN−K)位同学出列,使得剩下的KK位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,…,K1,2,…,K,他 ...
- dp(最长升序列)
http://poj.org/problem?id=2533 题意:给你n(1-1000)个数,求这n个数的最长升序列. 题解:dp[i]表示以第i个数结尾的最长升序列. #include & ...
- 521.最长特殊序列 I
2020-05-14 最长特殊序列 I 给你两个字符串,请你从这两个字符串中找出最长的特殊序列. 「最长特殊序列」定义如下:该序列为某字符串独有的最长子序列(即不能是其他字符串的子序列). 子序列 可 ...
- XHXJ's LIS HDU - 4352 最长递增序列&数位dp
代码+题解: 1 //题意: 2 //输出在区间[li,ri]中有多少个数是满足这个要求的:这个数的最长递增序列长度等于k 3 //注意是最长序列,可不是子串.子序列是不用紧挨着的 4 // 5 // ...
- [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列
Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...
- [LeetCode] Longest Consecutive Sequence 求最长连续序列
Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...
- lintcode: 最长连续序列
最长连续序列 给定一个未排序的整数数组,找出最长连续序列的长度. 说明 要求你的算法复杂度为O(n) 样例 给出数组[100, 4, 200, 1, 3, 2],这个最长的连续序列是 [1, 2, 3 ...
随机推荐
- Nginx整合Tomcat
现在先不考虑集群的配置问题,只实现Nginx实现一台tomact的代理 1.我们需要一个web项目,这里我把先准备好的web.war文件部署到Tomact服务器上 mvn clean install ...
- PAT B1023 组个最小数(20)
题目描述 给定数字 0-9 各若干个.你可以以任意顺序排列这些数字,但必须全部使用.目标是使得最后得到的数尽可能小(注意 0 不能做首位).例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的 ...
- 从入门到自闭之Python--Redis
什么是Redis Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库.Redis全称为:Remote Dictionary Server ...
- T100——自动执行设置了但没执行
azzi950设置了背景定时执行,但到底没执行, 重启的命令如下.三个命令都执行一下.指令 1: r.r azzp950 kill 指令 2: r.r azzp951 kill 指令 3: r.r a ...
- 手动导入jar到本地mvn仓库
<dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId ...
- Hinton等人最新研究:大幅提升模型准确率,标签平滑技术到底怎么用?
Hinton等人最新研究:大幅提升模型准确率,标签平滑技术到底怎么用? 2019年07月06日 19:30:55 AI科技大本营 阅读数 675 版权声明:本文为博主原创文章,遵循CC 4.0 B ...
- C Looooops
看了半天的同余 扩展欧几里得 练练手 C Looooops Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 27079 A ...
- Python(七) —— mock接口开发
mock接口开发 接口开发有很多框架,诸如 Django,flask,相比较而言,flask 是轻量级web开发框架,用来开发 mock 接口的不二之选.那你可能会问,什么叫 mock 接口呢?moc ...
- RAII惯用法:C++资源管理的利器(转)
RAII惯用法:C++资源管理的利器 RAII是指C++语言中的一个惯用法(idiom),它是“Resource Acquisition Is Initialization”的首字母缩写.中文可将其翻 ...
- centos7安装nginx服务
Nginx发音引擎x是一个免费的开源高性能HTTP和反向代理服务器,负责处理互联网上一些最大的网站的负载. 本教程将教你如何在你的CentOS Linux 7.5机器上安装和管理Nginx. 安装Ng ...