BZOJ3591: 最长上升子序列
因为是一个排列,所以可以用$n$位二进制数来表示$O(n\log n)$求LIS时的单调栈。
首先通过$O(n^22^n)$的预处理,求出每种LIS状态后面新加一个数之后的状态。
设$f[i][j]$表示已选数字集合为$i$,LIS状态为$j$的方案数。
转移时枚举不在$i$里的数$t$,如果$t$在给定的LIS中,那么它加入时需要检验它的前一个是否已经被加入。
对于状态的存储,可以考虑三进制,0表示没选,1表示选了但是不在栈中,2表示在栈里。那么只要将两个二进制数看作三进制,然后相加即可。
时间复杂度$O(n3^n)$。
#include<cstdio>
#define N 15
int n,m,i,j,k,p[N],g[N][1<<N],pow[N],a[1<<N],f[14348907],ans;
int main(){
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)p[i]=-1;
for(i=0;i<m;i++)scanf("%d",&j),p[j-1]=k-1,k=j;
for(pow[0]=i=1;i<n;i++)pow[i]=pow[i-1]*3;
for(i=0;i<1<<n;i++)for(j=0;j<n;j++)if(!(i>>j&1)){
g[j][i]=i|(1<<j);
for(k=j+1;k<n;k++)if(i>>k&1)break;
if(k<n)g[j][i]^=1<<k;
}else a[i]+=pow[j];
for(i=0;i<n;i++)if(p[i]<0)f[pow[i]<<1]=1;
for(i=1;i<1<<n;i++)for(k=0;k<n;k++)if(!(i>>k&1)){
if(~p[k])if(!(i>>p[k]&1))continue;
for(j=i;j;j=(j-1)&i)if(f[a[i]+a[j]])f[a[i|(1<<k)]+a[g[k][j]]]+=f[a[i]+a[j]];
}
for(i=1;i<1<<n;i++)if(__builtin_popcount(i)==m)ans+=f[a[(1<<n)-1]+a[i]];
return printf("%d",ans),0;
}
BZOJ3591: 最长上升子序列的更多相关文章
- 【dp 状态压缩 单调栈】bzoj3591: 最长上升子序列
奇妙的单调栈状压dp Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个 ...
- BZOJ3591 最长上升子序列(状压dp)
之前听说过一种dp套dp的trick,大致是用另一个dp过程中用到的一些东西作为该dp的状态.这个题比较类似. 考虑求LIS时用到的单调队列.设f[S]为所选取集合为S的方案数,其中在单调队列内的标2 ...
- 用python实现最长公共子序列算法(找到所有最长公共子串)
软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
- [Data Structure] LCSs——最长公共子序列和最长公共子串
1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...
- 动态规划求最长公共子序列(Longest Common Subsequence, LCS)
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
- LintCode 77: 最长公共子序列
public class Solution { /** * @param A, B: Two string. * @return: the length of the longest common s ...
- 最长下降子序列O(n^2)及O(n*log(n))解法
求最长下降子序列和LIS基本思路是完全一样的,都是很经典的DP题目. 问题大都类似于 有一个序列 a1,a2,a3...ak..an,求其最长下降子序列(或者求其最长不下降子序列)的长度. 以最长下降 ...
- 删除部分字符使其变成回文串问题——最长公共子序列(LCS)问题
先要搞明白:最长公共子串和最长公共子序列的区别. 最长公共子串(Longest Common Substirng):连续 最长公共子序列(Longest Common Subsequence,L ...
随机推荐
- 3.2 STL中的函数对象类模板
*: STL中有一些函数对象类模板,如下所示: 1)例如要求两个double类型的x 和y 的积,可以: multiplies<double>()(x,y); 该表达式的值就是x*y的值. ...
- ManageEngine Glossary
https://www.manageengine.com/products/applications_manager/help/glossary-applications-manager.html#s ...
- Java并发编程实现概览
并发概览 >>同步 如何同步多个线程对共享资源的访问是多线程编程中最基本的问题之一.当多个线程并发访问共享数据时会出现数据处于计算中间状态或者不一致的问题,从而影响到程序的正确运行.我们通 ...
- 无废话Android之listview入门,自定义的数据适配器、采用layoutInflater打气筒创建一个view对象、常用数据适配器ArrayAdapter、SimpleAdapter、使用ContentProvider(内容提供者)共享数据、短信的备份、插入一条记录到系统短信应用(3)
1.listview入门,自定义的数据适配器 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/and ...
- Delphi基础语法的学习笔记和注意事项总结
以下是我在自学Delphi的时候,对一些注意点的简单总结,并没有什么系统性可言,只是一个学习时顺手记下的笔记,主要为了当时加深对知识的印象,并没有希望能在以后的复习和使用Delphi中有什么多大的参考 ...
- SQL分组和聚合(Grouping and Aggregates)
这章应该是难点,也是成为SQL高手的必经之路. 注意有GROUP 语句时,WHERE和HAVING的场合. 前者用于检索前的条件过滤 . 后者用于检索出来结果之后的条件过滤. ========== ; ...
- 使用Mybatis-Generator自动生成Dao、Model、Mapping相关文件(转)
Mybatis属于半自动ORM,在使用这个框架中,工作量最大的就是书写Mapping的映射文件,由于手动书写很容易出错,我们可以利用Mybatis-Generator来帮我们自动生成文件. 1.相关文 ...
- 【计算机图形学】openGL常用函数
OpenGL常用函数 glAccum 操作累加缓冲区 glAddSwapHintRectWIN 定义一组被 SwapBuffers拷贝的三角形 glAlphaFunc允许设置alpha检测 ...
- 笔记本电脑关闭小键盘(即打字按P出现星号键)
开关方法:Fn + NumLk (联想电脑的NumLk 一般为F8,其他电脑自己在键盘找找罗)
- Javascript实现时钟
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...