排列统计

\(Description\)

对于给定的一个长度为n的序列{B[n]},问有多少个序列{A[n]}对于所有的i满足:A[1]~A[i]这i个数字中有恰好B[i]个数字小等于i。其中{A[n]}为1~n的一个排列,即1~n这n个数字在序列A[I]中恰好出现一次。 数据保证了至少有一个排列满足B序列。

\(Input\)

输入的第1行为一个正整数N,表示了序列的长度。

第2行包含N个非负整数,描述了序列{B[i]}。

\(Output\)

输出仅包括一个非负整数,即满足的{A[i]}序列个数。

\(Sample Input\)

3

0 1 3

\(Sample Output\)

3

\(Hint\)

【样例说明】

  对于A序列为1~3的全排列分别对应的B序列如下(冒号左边为A序列,冒号右边为对应B的序列)

  1 2 3:1 2 3

  1 3 2:1 1 3

  2 1 3:0 2 3

  2 3 1:0 1 3

  3 1 2:0 1 3

  3 2 1:0 1 3

  所以有3个满足的A序列。

【数据说明】

  对于20%的数据,有N≤8;

  对于30%的数据,有N≤11且答案不大于20000;

  对于50%的数据,有N≤100;

  对于100%的数据,有N≤2000。

解题思路

其实很容易发现,当且仅当 \(B_i - B_{i-1} = {0 , 1 , 2}\) 时才有解

因为考虑到 \(B_i\) 和 \(B_{i-1}\) 的关系,前者是后者产生的数列再加入一个新的数

为了方便表达,记产生的数列为 \(a_{1..n}\)

那么新加入一个数,记为x , 它至多可以给 \(B_i\) 贡献 1(\(x <= i\)),此时可贡献的数从上限 \(i-1\) 提升到 \(i\) ,如果之前有一个数恰好等于 i,那么它又可以给 \(B_i\) 贡献 1

然后就找不到可贡献的了,即 \(B_i + 2 \geq B_{i-1}\) 时才可能构造数列

现在考虑如何求得答案

设 \(f_i\) 表示前 \(1..i\) 满足条件的数列数目,\(k = B_{i-1} - B_i\)

\[f_i =
\left \{
\begin{aligned}
f_{i-1} & & (k=0) \\
f_{i-1}[(i-B_{i-1})+(i-1-B_{i-1})] & & (k=1) \\
f_{i-1}(i-B_{i-1}-1)^2 & & (k=2)
\end{aligned}
\right.
\]

要用高精度!!!

代码参考

#include<cstdio>
using namespace std;
typedef long long LL; int b[2005] , n , ans[10005]; inline void mul(int x)
{
int g = 0;
for(register int i = 1; i <= ans[0]; i++)
{
ans[i] = ans[i] * x + g;
g = ans[i] / 10;
ans[i] = ans[i] % 10;
}
while(g)
{
ans[++ans[0]] = g;
g = ans[ans[0]] / 10;
ans[ans[0]] = ans[ans[0]] % 10;
}
} int main()
{
scanf("%d" , &n);
for(register int i = 1; i <= n; i++) scanf("%d" , &b[i]);
ans[0] = ans[1] = 1;
for(register int i = 1; i <= n; i++)
{
if (b[i] - b[i-1] == 1) mul(i - b[i-1] + i - 1 - b[i - 1]);
else if (b[i] - b[i-1] == 2) mul((i - b[i - 1] - 1) * (i - b[i - 1] - 1));
}
for(register int i = ans[0]; i; i--) printf("%d" , ans[i]);
}

JZOJ 排列统计的更多相关文章

  1. LA 3641 Leonardo的笔记本 & UVA 11077 排列统计

    LA 3641 Leonardo的笔记本 题目 给出26个大写字母的置换B,问是否存在要给置换A,使得 \(A^2 = B\) 分析 将A分解为几个循环,可以观察经过乘积运算得到\(A^2\)后,循环 ...

  2. 【XSY2668】排列统计 DP

    题目描述 给你一个长度为\(n\)的排列\(a\),每次要选择两个数,交换这两个数(这两个数可以相同).总共要交换\(k\)次. 最后要统计数列中有多少位置\(i\)满足\(\max_{j\leq i ...

  3. 英文词频统计的java实现方法

    需求概要 1.读取文件,文件内包可含英文字符,及常见标点,空格级换行符. 2.统计英文单词在本文件的出现次数 3.将统计结果排序 4.显示排序结果 分析 1.读取文件可使用BufferedReader ...

  4. loj 6433 「PKUSC2018」最大前缀和 题解【DP】【枚举】【二进制】【排列组合】

    这是个什么集合DP啊- 想过枚举断点但是不会处理接下来的问题了- 我好菜啊 题目描述 小 C 是一个算法竞赛爱好者,有一天小 C 遇到了一个非常难的问题:求一个序列的最大子段和. 但是小 C 并不会做 ...

  5. Pandas 之 描述性统计案例

    认识 jupyter地址: https://nbviewer.jupyter.org/github/chenjieyouge/jupyter_share/blob/master/share/panda ...

  6. SOS.dll(SOS 调试扩展)

      SecAnnotate.exe(.NET 安全批注器工具) SignTool.exe(签名工具) Sn.exe(强名称工具) SOS.dll(SOS 调试扩展)   SqlMetal.exe(代码 ...

  7. 数据库的CRUD操作

    一:数据库的CRUD操作,C是指create新增,R是指retrieve检索,U是指update更改,D是指delete删除 SQL语句分为3类: 1.DDL指数据定义语言如:create,drop, ...

  8. SRM 406(1-250pt, 1-500pt)

    DIV1 250pt 题意:有几家宠物店,vecort<int>A表示每家宠物店含有小狗占小狗总数的百分比.现在要做扇形统计图统计每家店的小狗百分比,如下图,问作出来的扇形统计图中最多含有 ...

  9. linux学习总结----mongoDB总结

    dbhelper.py 用户登录和注册(加密算法) 加密导包 import hashlib 或者使用Md5 加密 MongoDB ->JSON service mysql start servi ...

  10. [转]软件开发规范—模块开发卷宗(GB8567——88)

    做软件开发是有那么一套国准可参照的,当然就是那些文档了,这里列出一下所有软件开发的规范文档: 操作手册 用户手册 软件质量保证计划 软件需求说明书 概要设计说明书 开发进度月报 测试计划文档 测试分析 ...

随机推荐

  1. MySQL数据库下载以及启动软件的详细步骤

    第一步>>>在浏览器上百度上搜索MySQL 如何判断官网?有官网两个字的或者纯英文解释的大概率就是官网 第二步>>>点击DOWNLOAWDS 第三步>> ...

  2. Android 内存缓存框架 LruCache 的实现原理,手写试试?

    本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 前言 大家好,我是小彭. 在之前的文章里,我们聊到了 LRU 缓存淘汰算法,并且分析 Java 标准库中支持 ...

  3. C++动态链接MySQL库

    C++链接MySQL库 库安装目录 CMakeList cmake_minimum_required(VERSION 3.22) project(MySQLConnectionPool) includ ...

  4. Redis如何模糊匹配Key值

    Redis模糊匹配Key值 使用Redis的scan代替Keys指令: public Set<String> scan(String matchKey) { Set<String&g ...

  5. TypeError: Object(…) is not a function

    vue中遇到的这个错误 1. 先检查变量名或者函数名是否有重复定义 报这错之后看了好久,也没有发现starkflow上说的,重复定义了变量或者函数 2. vue的话 检查下函数写的位置,直接写到cre ...

  6. 进击的K8S:Kubernetes基础概念

    Kubernetes简介 Kubernetes简称K8S(因为k和s中间有8个字母),是一个开源的容器集群管理平台,基于Go语言编写. 使用K8S,将简化分布式系统上的容器应用部署,使得开发人员可以专 ...

  7. SQL语句查询关键字

    SQL语句查询关键字前戏 SQL语句中关键字的执行顺序和编写顺序并不是一致的,可能会错乱 eg: select id,name from userinfo;我们先写的select再写的from,但是执 ...

  8. axios 中get 和post传参

    axios中get和ppost传参的方式: params是添加到url的请求字符串中的,一般用于get请求. data是添加到请求体(body)中的, 一般用于post请求. 上面,只是一般情况. 其 ...

  9. 数据结构——八大排序算法(java部分实现)

    java基本排序算法 1.冒泡排序 顶顶基础的排序算法之一,每次排序通过两两比较选出最小值(之后每个算法都以从小到大排序举例)图片取自:[小不点的博客](Java的几种常见排序算法 - 小不点丶 - ...

  10. Java基础篇——Gui编程

    AWT 抽象窗口工具 组件:按钮(button) 文本域(textarea) ​ 标签(label) 容器(container)... Frame窗口 Frame frame = new Frame( ...