Description

给出一个长度为 m 的序列 A, 请你求出有多少种 1…n 的排列, 满足 A 是它的一个 LIS.

Input

第一行两个整数 n,m.
接下来一行 m 个整数, 表示 A.

Output

一行一个整数表示答案.

Sample Input

5 3
1 3 4

Sample Output

11

Data Constraint

对于前 30% 的数据, n ≤ 9;
对于前 60% 的数据, n ≤ 12;
对于 100% 的数据, 1 ≤ m ≤ n ≤ 15.

Solution

  • 考虑计算 LIS 时使用的经典方法。

  • 记一个数组 ff ,f[i]f[i] 表示当前长度为 ii 的单调上升序列的结尾的最小值。

  • 这个数组是一个单调不降的数组. 于是我们可以用二进制来表示它。

  • 设 f(S,S0)f(S, S_0) 表示当前选了集合 SS 里的数,LIS 的 ff 数组状态为 S0S_0 时的方案数。

  • 这不难转移,枚举在末尾加上哪个数即可。

  • 观察发现 S0S_0 一定属于 SS,所以可以压成三进制。

  • 每位用 0,1,20,1,2 分别表示还没选、选了且在单调上升序列、选了但不在单调上升序列。

  • 于是枚举状态,算出目前的单调上升序列,在枚举还没选的转移即可。

  • 注意枚举转移的数要按照 A 序列的顺序来。

  • 若枚举到某一状态,其中每个数都已经选了,且单调上升序列的长度就是 mm ,即可统计答案。

  • 时间复杂度 O(3N∗N)O(3^N*N) ,实际小很多,因为很多状态都遍历不到。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
int n,m,ans;
int a[17],b[17],c[17],p[17],f[14348907+5];
bool bz[17];
inline int read()
{int X=0,w=0; char ch=0;while(!isdigit(ch)) w|=ch=='-',ch=getchar();while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X;
}
int main()
{n=read(),m=read();for(int i=1;i<=m;i++){b[i]=read();if(b[i]<=b[i-1] || b[i]<1 || b[i]>n) return 0&printf("0");}for(int i=p[0]=1;i<=n;i++) p[i]=p[i-1]*3;f[0]=1;for(int i=0;i<p[n];i++)if(f[i]){bool pd=true;int tot=0,x=i;for(int j=n-1;j>=0;j--){c[j+1]=x/p[j];if(x>=p[j]){if(c[j+1]==1) a[++tot]=j+1;x%=p[j];}else pd=false;}reverse(a+1,a+1+tot);if(pd && tot==m) ans+=f[i];memset(bz,false,sizeof(bz));int num=1;while(num<=m && c[b[num]]) num++;while(num+1<=m) bz[b[++num]]=true;for(int j=1;j<=n;j++)if(!c[j] && !bz[j]){if(j>a[tot]){if(tot==m) continue;f[i+p[j-1]]+=f[i];}else{int y=upper_bound(a+1,a+1+tot,j)-a;f[i+p[j-1]+p[a[y]-1]]+=f[i];}}}printf("%d",ans);return 0;
}

JZOJ 5600. 【NOI2018模拟3.26】Arg相关推荐

  1. JZOJ 5602. 【NOI2018模拟3.26】Cti JZOJ 5057. 【GDSOI2017模拟4.13】炮塔

    Description 有一个 n × m 的地图, 地图上的每一个位置可以是空地, 炮塔或是敌人. 你需要操纵炮塔消灭敌人. 对于每个炮塔都有一个它可以瞄准的方向, 你需要在它的瞄准方向上确定一个它 ...

  2. JZOJ 5602. 【NOI2018模拟3.26】Cti

    题目 有一个n*m的地图, 地图上的每一个位置可以是空地, 炮塔或是敌人. 你需要操纵炮塔消灭敌人. 对于每个炮塔都有一个它可以瞄准的方向, 你需要在它的瞄准方向上确定一个它的攻击位置,当然也可以不进 ...

  3. 【NOI2018模拟3.26】Cti

    Description 有一个 n × m 的地图, 地图上的每一个位置可以是空地, 炮塔或是敌人. 你需要操纵炮塔消灭敌人. 对于每个炮塔都有一个它可以瞄准的方向, 你需要在它的瞄准方向上确定一个它 ...

  4. jzoj3058. 【NOIP2012模拟10.26】火炬手

    jzoj3058. [NOIP2012模拟10.26]火炬手 题目 Description Input Output Sample Input Sample Output Hint 分析 做法一 做法 ...

  5. JZOJ 5627. 【NOI2018模拟4.3】paint

    Description Input Output Sample Input 样例输入1 10 10 4 1 6 4 1 6 9 9 4 样例输入2 10 10 4 2 2 4 4 7 7 9 9 Sa ...

  6. JZOJ 5623. 【NOI2018模拟4.2】program

    Description Input Output Sample Input 10 5 8>6<2<>54< 4 7 1 10 4 4 2 9 8 10 Sample Ou ...

  7. JZOJ 5167. 【NOIP2017模拟6.26】下蛋爷

    Description Input Output Sample Input 5 he she her hers his hershe 0.30 5 Sample Output 0.163 0.031 ...

  8. jzoj 3058. 【NOIP2012模拟10.26】火炬手

    Description 全运会就要开始了,笨笨想成为湖南地区的火炬手,经过层层选拔,最终到了最后一关,这一关给出了一个正整数n(N<=100000),求一个最小的正整数m,使得n*m的十进制表示 ...

  9. JZOJ 5930. 【NOIP2018模拟10.26】山花

    Description 3.1 Background 春日的山中灌木茂盛,几乎长到了人的腰间,将山间都铺满了绿色.雨后的灌木之间还带着晨露,总会沾湿走过的行人的衣裳. 林中枝叶茂密,不过树木长的并不紧 ...

最新文章

  1. 哈希--直接定值法和除留取余法
  2. OpenGL ES着色器语言之变量和数据类型
  3. (jquery插件)打造百分比动态色彩条
  4. Catch That Cow【广搜】
  5. Docker简介和安装
  6. KVM-Arch-Figure
  7. 安装allennlp库
  8. 2017CV技术报告:从3D物体重建到人体姿态估计
  9. python开发酷q插件gui_酷Q的SDK模块机器人个人开发插件
  10. 用计算机就行DNA翻译的程序,南邮通达科技英语原文翻译Lession 2 CTEXT
  11. 数据分析之帕累托(贡献度)分析
  12. 基础篇——人工智能相关方向学习路线指引
  13. [Redis] Redis实战
  14. 优化了的过关键点的光滑曲线拟合算法
  15. JAVA计算机毕业设计科院垃圾分类系统部署+源码+数据库+系统+lw文档
  16. java地图点线面_点线面类型互转
  17. Java写的十六进制转十进制和Ascii工具
  18. Cocos creator 导入 tiled map地图资源,cocos 显示地图错乱偏移
  19. Java基础(十二)
  20. Linux-Ngrok内网穿透

热门文章

  1. 使用Oracle数据库开发中的一个技巧
  2. (转)Python 用hashlib求中文字符串的MD5值
  3. Python学习笔记:线程和进程(合),分布式进程
  4. CentOS下挂载iso文件
  5. mount and fstab的使用(整理)
  6. 计算机游戏的英语怎么写,电脑游戏英语怎么写
  7. 【Leetcode】二叉树展开为列表(递归思想)
  8. [一维粒子模拟 version3.6]renormalization
  9. RuntimeError: ‘cryptography‘ package is required for sha256_password or caching_sha2_password auth m
  10. c++ 读文件_Linux文件(文件夹)详解