奇妙的单调栈状压dp

Description

给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数。

Input

第一行一个整数n。
第二行一个整数k,表示最长上升子序列的长度。
第三行k个整数,表示这个最长上升子序列。

Output

第一行一个整数,表示原排列可能的种类数。

Sample Input

5
3
1 3 4

Sample Output

11

HINT

【样例说明】

11种排列分别为(1, 3, 2, 5, 4), (1, 3, 5, 2, 4), (1, 3, 5, 4, 2), (1, 5, 3, 2, 4), (1, 5, 3, 4, 2), (2, 1, 3, 5, 4), (2, 1, 5, 3, 4), (2, 5, 1, 3, 4), (5, 1, 3, 2, 4), (5, 1, 3, 4, 2), (5, 2, 1, 3, 4)。

【数据规模和约定】

对于30%的数据,1 <= n <= 11。

对于70%的数据,1 <= n <= 14。

对于100%的数据,1 <= n <= 15,答案小于2^31。


题目分析

这种属于奇奇怪怪的状压dp:把单调栈拿来状压。

考虑求解LIS,是一个使用单调栈的过程。因此按序列位置依次考虑,每一个数有三种状态:0:没有被考虑;1:考虑了,在栈里;2:考虑了,已出栈————自然可以三进制状压表示。

再考虑dp的过程:用$f[i]$表示$i$这个三进制状态下的合法方案数。转移时则从小到大枚举每一个数,看其是否能够通过当前状态合法转移至下一个LIS(注意判断转移前的合法性)。

转移不难,重点在于想到状压每个数对于单调栈的状态。

 #include<bits/stdc++.h>
const int maxn = ; int val[maxn],base[maxn],n,m;
int num[maxn],pre[maxn];
int LIS[maxn],cnt;
int f[],ans;      //f[]不要忘记开大,表示3^n种状态 int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
int main()
{
n = read(), m = read(), num[] = ;
for (int i=; i<=m; i++)
{
num[i] = read()-, pre[num[i]] = i-;
if (num[i] < num[i-]){
puts("");
return ;
}
}
base[] = ;
for (int i=; i<=n; i++) base[i] = base[i-]*;
f[] = ;
for (int i=; i<base[n]; i++)
if (f[i]){
int st = i,done,cnt,ins;
done = cnt = ins = ;
for (int j=; j<n; j++)
{
val[j] = st%, st /= ;
if (val[j]) done++;
if (val[j]==) LIS[cnt++] = j;
}
if (done==n){
ans += f[i];
continue;
}
for (int j=; j<n; j++)
{
if (val[j]) continue;
if (pre[j]&&!val[num[pre[j]]]) continue;
while (LIS[ins] < j&&ins < cnt) ins++;
if (ins==m) continue;
int nxt = i+base[j];
if (ins < cnt) nxt += base[LIS[ins]];
f[nxt] += f[i];
}
}
printf("%d\n",ans);
return ;
}

END

【dp 状态压缩 单调栈】bzoj3591: 最长上升子序列的更多相关文章

  1. hdu_4352_XHXJ's LIS(数位DP+状态压缩)

    题目连接:hdu_4352_XHXJ's LIS 题意:这题花大篇篇幅来介绍电子科大的一个传奇学姐,最后几句话才是题意,这题意思就是给你一个LL范围内的区间,问你在这个区间内最长递增子序列长度恰为K的 ...

  2. HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

    题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...

  3. HDU 1074 Doing Homework (dp+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一 ...

  4. hdu 4352 数位dp + 状态压缩

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. 【bzoj1076】[SCOI2008]奖励关 期望dp+状态压缩dp

    题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再 ...

  6. hdu4336 Card Collector(概率DP,状态压缩)

    In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, fo ...

  7. dp状态压缩

    dp状态压缩 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了.难点在于以下几个方面:状 ...

  8. 洛谷 1052 dp 状态压缩

    洛谷1052 dp 状态压缩 传送门 (https://www.luogu.org/problem/show?pid=1052#sub) 做完这道题之后,感觉涨了好多见识,以前做的好多状压题目都是将一 ...

  9. 「10.11」chess(DP,组合数学)·array(单调栈)·ants(莫队,并茶几)

    菜鸡wwb因为想不出口胡题所以来写题解了 A. chess 昨天晚上考试,有点困 开考先花五分钟扫了一边题,好开始肝$T1$ 看了一眼$m$的范围很大,第一反应矩阵快速幂?? $n$很小,那么可以打$ ...

随机推荐

  1. hdu 6319 Problem A. Ascending Rating (2018 Multi-University Training Contest 3)

    #include <stdio.h> #include <iostream> #include <cstdlib> #include <cmath> # ...

  2. hdu6318( 2018 Multi-University Training Contest 2)

    bryce1010模板 http://acm.hdu.edu.cn/showproblem.php?pid=6318 求逆序数的对数 #include<iostream> #include ...

  3. C#操作Windows用户

    首先需要引入System.DirectoryServices.dll using System; using System.Collections.Generic; using System.Dire ...

  4. arcengine 将地图文件保存为图片(包括各种图片格式)

    1,最近做了个地图文件输出图片的功能,思想主要就是利用MapControl的ActiveView中的out方法: 2代码如下:欢迎交流指正 SaveFileDialog m_save = new Sa ...

  5. 一本通 1434:【例题2】Best Cow Fences

    Best Cow Fences 二分答案 + 前缀和 个人认为题意没有表述清楚,本题要求的是满足题意的连续子序列(难度大大降低了有木有). 本题的精度也是非常令人陶醉,请您自行体会吧! #includ ...

  6. leetcode287 Find the Duplicate Number

    思路: 转换成链表之后使用floyed判环法.转换之后重复的那个数字是唯一一个有多个前驱和一个后继的节点,因此是环的起始节点. 实现: class Solution { public: int fin ...

  7. iOS 锁的常用方法

    锁的用法在iOS中有几种方法来解决多线程访问同一个内存地址的互斥同步问题: 方法一,@synchronized(id anObject),(最简单的方法)会自动对参数对象加锁,保证临界区内的代码线程安 ...

  8. AzureARM 使用 powershell 扩容系统磁盘大小

    azure中的虚拟机,windows磁盘大小为127G,linux磁盘大小为30G,在很多时候部署应用程序时直接部署到系统磁盘内导致磁盘后期容量不够需要扩容,在执行分区扩容前我们需要先通过Potal或 ...

  9. azure 创建redhat镜像帮助

    为 Azure 准备基于 Red Hat 的虚拟机 从 Hyper-V 管理器准备基于 Red Hat 的虚拟机 先决条件 本部分假定你已经从 Red Hat 网站获取 ISO 文件并将 RHEL 映 ...

  10. uvm_subscriber——告诉她我们来过

    Subscribers are basically listeners of an analysis port. They subscribe to a broadcaster and receive ...