之前听说过一种dp套dp的trick,大致是用另一个dp过程中用到的一些东西作为该dp的状态。这个题比较类似。

  考虑求LIS时用到的单调队列。设f[S]为所选取集合为S的方案数,其中在单调队列内的标2不在的标1。转移时考虑选择一个数是否合法,这只需要保证LIS长度不超过k且所给数的相对顺序不变。

  注意dp顺序,从小到大先枚举选了哪些数再枚举哪些在单调队列里。以及注意卡常。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 15
int n,m,id[N],p[N+],f[];
bool flag[<<N][N];
int v[<<N][N],c[<<N],mx[<<N],s[<<N],ans=;
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3591.in","r",stdin);
freopen("bzoj3591.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();
for (int i=;i<=m;i++) id[read()-]=i;
p[]=;for (int i=;i<=n;i++) p[i]=p[i-]*;
for (int i=;i<(<<n);i++)
for (int j=;j<n;j++)
if (!(i&(<<j)))
{
if (!id[j]) flag[i][j]=;
else
{
int tot=;
for (int k=;k<n;k++)
if ((i&(<<k))) tot+=(id[k]>);
if (tot+==id[j]) flag[i][j]=;
}
int t=-,x=;
for (int k=;k<n;k++)
if (i&(<<k)) x+=p[k];
for (int k=n-;k>j;k--)
if (i&(<<k)) t=k;
if (~t) v[i][j]=x-p[t]+p[j];
else v[i][j]=x+p[j];
}
else c[i]+=p[j],mx[i]=max(mx[i],j),s[i]++;
f[]=;
for (int x=;x<(<<n);x++)
for (int y=x;y>||y==&&x==;x==?y--:y=y-&x)
if (f[c[x]+c[y]])
{
int i=c[x]+c[y],z=c[x];
for (int j=;s[y]==m?j<mx[y]:j<n;j++)
if (flag[x][j]) f[z+p[j]+v[y][j]]+=f[i];
if (x==(<<n)-) ans+=f[i];
}
cout<<ans;
return ;
}

BZOJ3591 最长上升子序列(状压dp)的更多相关文章

  1. 【bzoj5161】最长上升子序列 状压dp+打表

    题目描述 现在有一个长度为n的随机排列,求它的最长上升子序列长度的期望. 为了避免精度误差,你只需要输出答案模998244353的余数. 输入 输入只包含一个正整数n.N<=28 输出 输出只包 ...

  2. BZOJ.3591.最长上升子序列(状压DP)

    BZOJ 题意:给出\(1\sim n\)的一个排列的一个最长上升子序列,求原排列可能的种类数. \(n\leq 15\). \(n\)很小,参照HDU 4352这道题,我们直接把求\(LIS\)时的 ...

  3. bzoj5161 最长上升子序列 状压DP(DP 套 DP) + 打表

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5161 题解 回顾一下以前用二分求 LIS 的方法:令 \(f[i]\) 表示长度为 \(i\) ...

  4. BZOJ 5161: 最长上升子序列 状压dp+查分

    好神啊 ~ 打表程序: #include <cstdio> #include <cstring> #include <algorithm> #define N 14 ...

  5. 洛谷 P4484 - [BJWC2018]最长上升子序列(状压 dp+打表)

    洛谷题面传送门 首先看到 LIS 我们可以想到它的 \(\infty\) 种求法(bushi),但是对于此题而言,既然题目出这样一个数据范围,硬要暴搜过去也不太现实,因此我们需想到用某种奇奇怪怪的方式 ...

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

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

  7. hdu 4352 "XHXJ's LIS"(数位DP+状压DP+LIS)

    传送门 参考博文: [1]:http://www.voidcn.com/article/p-ehojgauy-ot.html 题解: 将数字num字符串化: 求[L,R]区间最长上升子序列长度为 K ...

  8. hdu4352-XHXJ's LIS状压DP+数位DP

    (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 题意:传送门  原题目描述在最下面.  在区间内把整数看成一个阿拉伯数字的集合,此集合中最长严格上升子序列的长度为k的个数. 思路: ...

  9. 「算法笔记」状压 DP

    一.关于状压 dp 为了规避不确定性,我们将需要枚举的东西放入状态.当不确定性太多的时候,我们就需要将它们压进较少的维数内. 常见的状态: 天生二进制(开关.选与不选.是否出现--) 爆搜出状态,给它 ...

  10. fzu2188 状压dp

    G - Simple String Problem Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & ...

随机推荐

  1. nginx 反向代理到目录

    upstream yg{ server 127.0.0.x; } server { listen 80; server_name www.hikaru.pw; location / { rewrite ...

  2. Android Studio 3.1.2 Device File Explorer nothing to show

    Android Studio 3.1.2 Device File Explorer nothing to  show 不显示 目录  ,空白 手持终端设备: Android  4.2.2  ,API1 ...

  3. 在Notepad++中为Python配置编译环境

    方法1:按下F5 输入d:\Python25\python.exe "$(FULL_CURRENT_PATH)" 其中"d:\Python25\python.exe&qu ...

  4. MindMaster安装教程以及激活破解教程

    原文地址:https://www.jianshu.com/p/16d2fc7d8e45 第一.激活必须首先断网 第二.运行安装程序,安装完成后先不要打开 第三.把Cracks文件夹下的文件复制到软件安 ...

  5. 使用Git提交与管理代码

    要成为一个合格的码农,必须要有效对自己的代码进行管理,最近打算有空就整理一下自己以前写得代码,把不涉及实验室的机密的内容等放到github上,之前只知道git clone 别人的代码,希望有一天自己的 ...

  6. flask ssti python2和python3 注入总结和区别

    总结一下flask ssti的注入语句 代码 import uuid from flask import Flask, request, make_response, session,render_t ...

  7. Unity FSM 有限状态机

    翻译了一下unity wiki上对于有限状态机的案例,等有空时在详细写一下.在场景中添加两个游戏物体,一个为玩家并修改其Tag为Player,另一个为NPC为其添加NPCControl脚本,并为其将玩 ...

  8. ZT-----用javascrip写一个区块链

    几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术.在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的.我将会称之 ...

  9. Java基础知识:Java实现Map集合二级联动2

    2. 定义获取省份的方法,创建一个Map集合,将上一步得到的映射集合赋值给它,使用Map集合的keySet()方法获取该集合中的所有键对象组成的Set 集合,即为省分集合,创建一个Object型一维数 ...

  10. VMware VSAN 入门与配置(一)

    ----VMware VSAN beta版已经出来一段时间了,今天终于正式发布(同时VMware View 5.3.1也正是发布,在5.3的基础上增加了VSAN的支持) VSAN 产品主页 http: ...