最长上升序列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的更多相关文章

  1. CJOJ 【DP合集】最长上升序列2 — LIS2

    题面 已知一个 1 ∼ N 的排列的最长上升子序列长度为 K ,求合法的排列个数. 好题(除了我想不出来我应该找不到缺点), 想一想最长上升子序列的二分做法, 接在序列后面或者替换. 所以对于每一个位 ...

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

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

  3. P1091 合唱队形 DP 最长升序列维护

    题目描述 NN位同学站成一排,音乐老师要请其中的(N-KN−K)位同学出列,使得剩下的KK位同学排成合唱队形. 合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2,…,K1,2,…,K,他 ...

  4. dp(最长升序列)

    http://poj.org/problem?id=2533   题意:给你n(1-1000)个数,求这n个数的最长升序列.   题解:dp[i]表示以第i个数结尾的最长升序列. #include & ...

  5. 521.最长特殊序列 I

    2020-05-14 最长特殊序列 I 给你两个字符串,请你从这两个字符串中找出最长的特殊序列. 「最长特殊序列」定义如下:该序列为某字符串独有的最长子序列(即不能是其他字符串的子序列). 子序列 可 ...

  6. XHXJ's LIS HDU - 4352 最长递增序列&数位dp

    代码+题解: 1 //题意: 2 //输出在区间[li,ri]中有多少个数是满足这个要求的:这个数的最长递增序列长度等于k 3 //注意是最长序列,可不是子串.子序列是不用紧挨着的 4 // 5 // ...

  7. [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列

    Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...

  8. [LeetCode] Longest Consecutive Sequence 求最长连续序列

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...

  9. lintcode: 最长连续序列

    最长连续序列 给定一个未排序的整数数组,找出最长连续序列的长度. 说明 要求你的算法复杂度为O(n) 样例 给出数组[100, 4, 200, 1, 3, 2],这个最长的连续序列是 [1, 2, 3 ...

随机推荐

  1. 【转】redis数据库入门教程(全面详细)+面试问题

    [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 – 简介8.redis ...

  2. 神奇的负margin解决border“合并”

    如上图所示,这是一个分页样式,a:hover时,需要改变边框的颜色. 我们知道,除表格之外,其他标签的border是不能合并的.要解决这个问题,思路有三: 1.table布局(大概很少有人愿意在这里使 ...

  3. GridControl gridView显示筛选行,设置条件为包含

    public static void SetFilter(GridView gdv) {     gdv.OptionsView.ShowAutoFilterRow = true; //设置筛选行  ...

  4. element-ui tree控件获取当前节点和父节点

    今天使用element-ui 遇到两个问题,第一个问题是获取tree控件的当前节点和父节点, 一开始使用tree控件的getCurrentNode()函数,结果发现返回的是当前节点的data属性,和u ...

  5. CentOS 修改/etc/resolv.conf 重启network后又恢复到原来的状态?

    问题描述:CentOS 修改/etc/resolv.conf 执行service network restart后,/etc/resolv.conf又恢复到原来的状态 解决方法:/etc/resolv ...

  6. asp.net 10 Cookie & Session

    Cookie 1.什么是Cookie 一小段文本,明文的数据,关于网站相关的文本字符串数据.一个客户端状态保持机制~ 存储在客户端的浏览器内存里面或者磁盘(如果不指定过期时间,那么存储在客户端浏览器内 ...

  7. HTTP缓存总结

    在具体了解 HTTP 缓存之前先来明确几个术语:1.缓存命中率:从缓存中得到数据的请求数与所有请求数的比率.理想状态是越高越好.2.过期内容:超过设置的有效时间,被标记为“陈旧”的内容.通常过期内容不 ...

  8. js相关的时间获取方法

    1.获取时间 var time=new Date();//返回的是GMT,格林尼治标准时间. console.log(time)://Thu Jul 27 2017 16:55:21 GMT+0800 ...

  9. Linux系统目录结构和文件基本属性

    一.Linux系统目录结构 二.Linux 文件基本属性 三.touch stat tar 命令 一.Linux系统目录结构 不同颜色文件的含义: inux 文件颜色的含义,蓝色代表目录,绿色代表可执 ...

  10. Oracle【序列、索引、视图、分页】

    1.Oracle序列语法:create sequence 序列名 特点1:默认是无值,指针指向没有值的位置 特点2:序列名.nextval 每次执行值会自增一次,步长为 1 特点3:序列名.currv ...