BZOJ.3591.最长上升子序列(状压DP)
题意:给出\(1\sim n\)的一个排列的一个最长上升子序列,求原排列可能的种类数。
\(n\leq 15\)。
\(n\)很小,参照HDU 4352这道题,我们直接把求\(LIS\)时的状态存下来做DP数组的状态。
状态就是那个单调递增的单调栈。每个数会有三种可能:没入过栈,现在在栈中,之前在栈中但是被替换掉了。
所以用一个\(n\)位三进制数表示单调栈的状态\(s\)。然后枚举状态\(s\),再枚举一个没出现过的数,很好转移。
转移时注意\(LIS\)长度不能超过\(k\),以及要能形成给定的\(LIS\)即可(现在加入的数如果在给定的\(LIS\)中,那它在\(LIS\)中的前一个数要出现过,后一个数没出现过)。
复杂度\(O(n3^n)\)。加点剪枝问题不大。
其实可以把非\(0\)的状态扔到一个queue
里,不用\(3^n\)地for
。
//56872kb 1472ms
#include <cstdio>
#include <algorithm>
typedef long long LL;
const int N=20;
int main()
{
static int A[N],id[N],pw[N],sta[N],lis[N],f[14348909];
int n,K; scanf("%d%d",&n,&K);
for(int i=1; i<=K; ++i) scanf("%d",&A[i]), id[--A[i]]=i;
pw[0]=1;
for(int i=1; i<=n; ++i) pw[i]=pw[i-1]*3;
int ans=0;
f[0]=1, sta[A[0]=n]=1, sta[A[K+1]=n+1]=0;
for(int s=0,v; s+1<pw[n]; ++s)
if((v=f[s]))
{
int cnt=0,tot=0;
for(int i=0,tmp=s; i<n; ++i,tmp/=3)
tot+=((sta[i]=tmp%3)>0), sta[i]==1&&(lis[cnt++]=i);
if(tot==n) {ans+=v; continue;}//三进制啊...最后答案不只是f[pw[n]-1]
lis[cnt]=20;
for(int i=0; i<n; ++i)
if(!sta[i])
{
if(id[i] && (!sta[A[id[i]-1]]||sta[A[id[i]+1]])) continue;
int j=0;
while(lis[j]<i) ++j;
if(j==K) continue;//length>K
f[s+pw[i]+(j==cnt?0:pw[lis[j]])]+=v;//pw[lis[j]] not pw[j]..
}
}
printf("%d\n",ans);
return 0;
}
BZOJ.3591.最长上升子序列(状压DP)的更多相关文章
- BZOJ 5161: 最长上升子序列 状压dp+查分
好神啊 ~ 打表程序: #include <cstdio> #include <cstring> #include <algorithm> #define N 14 ...
- 【bzoj5161】最长上升子序列 状压dp+打表
题目描述 现在有一个长度为n的随机排列,求它的最长上升子序列长度的期望. 为了避免精度误差,你只需要输出答案模998244353的余数. 输入 输入只包含一个正整数n.N<=28 输出 输出只包 ...
- bzoj5161 最长上升子序列 状压DP(DP 套 DP) + 打表
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=5161 题解 回顾一下以前用二分求 LIS 的方法:令 \(f[i]\) 表示长度为 \(i\) ...
- [BZOJ 1072] [SCOI2007] 排列perm 【状压DP】
题目链接:BZOJ 1072 这道题使用 C++ STL 的 next_permutation() 函数直接暴力就可以AC .(使用 Set 判断是否重复) 代码如下: #include <io ...
- BZOJ 3195 [Jxoi2012]奇怪的道路 | 状压DP
传送门 BZOJ 3195 题解 这是一道画风正常的状压DP题. 可以想到,\(dp[i][j][k]\)表示到第\(i\)个点.已经连了\(j\)条边,当前\([i - K, i]\)区间内的点的度 ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- BZOJ 3446: [Usaco2014 Feb]Cow Decathlon( 状压dp )
水状压dp. dp(x, s) = max{ dp( x - 1, s - {h} ) } + 奖励(假如拿到的) (h∈s). 时间复杂度O(n * 2^n) ------------------- ...
- BZOJ 2734 [HNOI2012]集合选数 (状压DP、时间复杂度分析)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2734 题解 嗯早就想写的题,昨天因为某些不可告人的原因(大雾)把这题写了,今天再来写题解 ...
- 【刷题】BZOJ 3591 最长上升子序列
Description 给出1~n的一个排列的一个最长上升子序列,求原排列可能的种类数. Input 第一行一个整数n. 第二行一个整数k,表示最长上升子序列的长度. 第三行k个整数,表示这个最长上升 ...
随机推荐
- HTML&javaSkcript&CSS&jQuery&ajax-Css
CSS 1 .eg <head> <style> body{ background-color:#d0e4fe;} h1{ color:orange; text-alin:ce ...
- 解决npm install过程中报错:unable to verify the first certificate
今天使用npm安装开发包时遇到“unable to verify the first certificate”(无法验证第一证书)这个问题 原因:2014年2月27日,npm不再支持自签名证书.因为n ...
- Nginx详解二十四:Nginx深度学习篇之灰度发布
实战场景 - 灰度发布 灰度发布的作用:按照一定的关系区别,分部分的代码进行上线,使代码的发布能平滑过渡上线实现方式: 1.用户的信息cookie等信息区别 2.根据用户的IP地址 安装memcach ...
- Shiro+Redis实现tomcat集群session共享
一.背景 当我们使用了nginx做项目集群以后,就会出现一个很严重的问题亟待解决,那就是:tomcat集群之间如何实现session共享的问题,如果这个问题不解决,就会出现登陆过后再次请求资源依旧 ...
- java函数式编程之Supplier
原创 2016年12月25日 10:02:52 标签: 函数式编程 / java 3250 描述:Supplier< T>接口没有入参,返回一个T类型的对象,类似工厂方法. 源码: pub ...
- .NET Framework 类库——C#命名空间大全
引用地址:https://msdn.microsoft.com/zh-cn/library/gg145045.aspx C# using引用时,不知道有哪些命名空间,这下转载收集一篇,方面查找使用. ...
- Choosing web framework: ASP.NET MVC vs Django Python vs Ruby on Rails(转载)
来源:http://podlipensky.com/2012/06/choosing-web-framework-asp-net-mvc-vs-django-python-vs-ruby-on-rai ...
- Ubuntu下使用Evernote
Ubuntu下安装使用Evernote http://blog.csdn.net/yangzhuoluo/article/details/8118996 http://blog.csdn.net/ya ...
- vscode git
Git 全局设置: git config --global user.name "xxxx" git config --global user.email "123456 ...
- net core体系-web应用程序-4asp.net core2.0 项目实战(1)-7项目缓冲方案( Redis)
本文目录1. 摘要2. Redis配置3. RedisHelper4.使用实例 5. 总结 1. 摘要 由于內存存取速度远高于磁盘读取的特性,为了程序效率提高性能,通常会把常用的不常变动的数据存储在 ...