jzoj3712 【NOI2014模拟6.30】石中剑的考验
来源:互联网 发布:centos 6 vsftp 配置 编辑:程序博客网 时间:2024/05/18 03:03
题意
给出一个元素不重复,长为n<=15的序列的最长上升子序列之一。
求有多少个序列满足有这个最长上升子序列。
分析
这tm也是一题玄学题。
因为n=15,考虑状压,dp.
一个序列只要满足两个条件就是合法序列: 1)最长上升子序列长度为k,2)子序列存在于原序列中。
第二个好求,直接状压。
问题是第一个。
因为我们要求最长上升子序列的长度,所以状态里要带一个dp时的f数组
这样超时。
想一想求最长上升子序列的n log n算法,我们发现只需要存一个长度为i的上升子序列的最小结尾元素 也就是“辅助栈”就可以更新序列最长上升子序列的长度了。
但是怎么存?
因为辅助栈是单调的,所以只需要知道每个数有没有在辅助栈里出现就好了。
于是我们状态就有了,一个三进制的压位状态。 0表示没有出现过,1表示出现过,2表示出现过并且在辅助栈内。
转移比较显然,但需要加几个优化。
1)转移时注意到,因为x从小到大枚举,所以更新指针也会往前指。复杂度是O(n)的
2)找一下合法的一个必要条件优化: 因为a[i]是最长上升子序列中第i位,所以他前面不应该存在一个数x使得x<=a[i]且f[x]>=i.
#include <cstdio>#include <iostream>#include <cstring>#include <algorithm>#define N 16using namespace std;int f[14348908];int n,k,a[N],g[N],app[N],t,su[N];int m[N],ans,stm;void dfs(int x,int cnt,int st) { if (x>n) { if (f[st]==0) return; ++stm; g[0]=0; int s=st,nst=0,now=0; for (int i=1; i<=n; i++) { int yss=s/3,ys=s-yss*3; if (ys!=0) app[i]=stm; if (ys==2) g[++g[0]]=i; s=yss; if (s==0) break; } for (int x=1; x<=n; x++) if (app[x]!=stm) { if (su[x]>1 && app[a[ su[x]-1 ]]!=stm) continue; while (now<g[0] && g[now+1]<x) now++; bool bz=0; for (int i=1; i<=k; i++) if (app[a[i]]!=stm && a[i]>x && now+1>=i) { bz=1; break; } if (bz==1) continue; if (now==0 && g[1]<now) nst=st+m[x]; //0->1 else if (now!=g[0]) { nst=st+m[x]*2; //0->2 nst=nst - m[g[now+1]]; //2->1 } else nst=st+m[x]*2;//0->2 f[nst]+=f[st]; if (t==n-1 && g[0]+(now==g[0])==k) ans=ans+f[st]; } return; } if (n-x+1>t-cnt) dfs(x+1,cnt,st*3); if (cnt<t) { dfs(x+1,cnt+1,st*3+1); dfs(x+1,cnt+1,st*3+2); }}int main() { freopen("sword.in","r",stdin); freopen("sword.out","w",stdout); cin>>n>>k; m[1]=1; for (int i=2; i<=n; i++) m[i]=m[i-1]*3; for (int i=1; i<=k; i++) scanf("%d",&a[i]),su[a[i]]=i; if (k==1) { cout<<1<<endl; return 0; } f[0]=1; for (t=0; t<n; t++) dfs(1,0,0); cout<<ans<<endl;}
阅读全文
0 0
- jzoj3712 【NOI2014模拟6.30】石中剑的考验
- JZOJ 3712【NOI2014模拟6.30】石中剑的考验
- 【NOI2014模拟6.30】Honor
- 【NOI2014模拟7.11】数学题
- 【NOI2014模拟6.20】慎二的随机数列
- JZOJ 3693. 【NOI2014模拟6.20】慎二的随机数列
- 【NOI2014模拟7.11】数学题(math)
- 【NOI2014模拟7.14】Problem A
- Jzoj3717【NOI2014模拟7.2】火车
- 结婚前的考验
- 每天都有新的考验
- 考验你的大脑
- 金钱的考验zz
- 经不起考验的感情
- 第一天的考验
- 20160929 - 再一次的考验
- 小学生的考验
- 女友的考验
- OpenCV系列学习之图像形态学
- 10.React中文之提升状态
- 大数据的一般学习路线图
- Golang教程:(十二)变参函数
- HoloLens 如何实现UI正对摄像机
- jzoj3712 【NOI2014模拟6.30】石中剑的考验
- 字符串处理
- 关于定制日期选择器DatePicker
- C语言可变参数
- Android APP性能优化总结(改写中,未完成)
- 查询数据库中的表的字段
- 直播聊天室消息类型
- 可拖动的滑动面板和Menu的实现(SlidingUpPanelLayout)
- 公开的海量数据集 Public Research-Quality Datasets