因为是一个排列,所以可以用$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: 最长上升子序列的更多相关文章

  1. 【dp 状态压缩 单调栈】bzoj3591: 最长上升子序列

    奇妙的单调栈状压dp Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个 ...

  2. BZOJ3591 最长上升子序列(状压dp)

    之前听说过一种dp套dp的trick,大致是用另一个dp过程中用到的一些东西作为该dp的状态.这个题比较类似. 考虑求LIS时用到的单调队列.设f[S]为所选取集合为S的方案数,其中在单调队列内的标2 ...

  3. 用python实现最长公共子序列算法(找到所有最长公共子串)

    软件安全的一个小实验,正好复习一下LCS的写法. 实现LCS的算法和算法导论上的方式基本一致,都是先建好两个表,一个存储在(i,j)处当前最长公共子序列长度,另一个存储在(i,j)处的回溯方向. 相对 ...

  4. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

  5. [Data Structure] LCSs——最长公共子序列和最长公共子串

    1. 什么是 LCSs? 什么是 LCSs? 好多博友看到这几个字母可能比较困惑,因为这是我自己对两个常见问题的统称,它们分别为最长公共子序列问题(Longest-Common-Subsequence ...

  6. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  7. LintCode 77: 最长公共子序列

    public class Solution { /** * @param A, B: Two string. * @return: the length of the longest common s ...

  8. 最长下降子序列O(n^2)及O(n*log(n))解法

    求最长下降子序列和LIS基本思路是完全一样的,都是很经典的DP题目. 问题大都类似于 有一个序列 a1,a2,a3...ak..an,求其最长下降子序列(或者求其最长不下降子序列)的长度. 以最长下降 ...

  9. 删除部分字符使其变成回文串问题——最长公共子序列(LCS)问题

    先要搞明白:最长公共子串和最长公共子序列的区别.    最长公共子串(Longest Common Substirng):连续 最长公共子序列(Longest Common Subsequence,L ...

随机推荐

  1. 求sqrt()底层效率问题(二分/牛顿迭代)

    偶然看见一段求根的神代码,于是就有了这篇博客: 对于求根问题,通常我们可以调用sqrt库函数,不过知其然需知其所以然,我们看一下求根的方法: 比较简单方法就是二分咯: 代码: #include< ...

  2. JavaScript基础——定义变量

    在JavaScript中使用变量来临时存储和访问来自JavaScript文件的数据.变量既可以指向简单的数据类型,如数字或者字符串:也可以指向更复杂的数据类型,比如对象. 在JavaScript中定义 ...

  3. mysql 源码安装

    yum install -y gcc gcc-c++ autoconf libjpeg libjpeg-devel perl perl-CPAN libpng libpng-devel freetyp ...

  4. 在ubuntu上搭建开发环境7---ubuntu安装JDK

    首先,当然是要下载了. 地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html 按 ...

  5. Delphi面向对象的可见性表示符

    Delphi能通过在声明域和方法的时候用protected.private.public.published和automated指示符来对对象提供进一步的控制.使用这些关键字的语法如下 TSomeOb ...

  6. Solr auto commit 配置

    为了解决写索引时频繁提交带来的效率问题,考虑使用自动提交. 在solrconfig.xml中增加以下代码: <updateHandler class="solr.DirectUpdat ...

  7. JS获取form表单的所有输入值

    function getFormQueryString(frmID) { var frmID=document.getElementById(frmID); var i,queryString = & ...

  8. Oracle优化的几个简单步骤

    数据库优化的讨论可以说是一个永恒的主题.资深的Oracle优化人员通常会要求提出性能问题的人对数据库做一个statspack,贴出数据库配置等等.还有的人认为要抓出执行最慢的语句来进行优化.但实际情况 ...

  9. hdu 4031 2011成都赛区网络赛A题 线段树 ***

    就是不知道时间该怎么处理,想了好久,看了别人的题解发现原来是暴力,暴力也很巧妙啊,想不出来的那种  -_-! #include<cstdio> #include<iostream&g ...

  10. PowerDesigner(PowerDesigner15.1.0.2850)下载、安装以及破解

    转自:http://www.cnblogs.com/Fonkie/articles/1600662.html 一.先安装PowerDesigner15(PowerDesigner15.1.0.2850 ...