转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud

Iahub and Permutations

Iahub is so happy about inventing bubble sort graphs that he's staying all day long at the office and writing permutations. Iahubina is angry that she is no more important for Iahub. When Iahub goes away, Iahubina comes to his office and sabotage his research work.

The girl finds an important permutation for the research. The permutation contains n distinct integers a1, a2, ..., an (1 ≤ ai ≤ n). She replaces some of permutation elements with -1 value as a revenge.

When Iahub finds out his important permutation is broken, he tries to recover it. The only thing he remembers about the permutation is it didn't have any fixed point. A fixed point for a permutation is an element ak which has value equal to k (ak = k). Your job is to proof to Iahub that trying to recover it is not a good idea. Output the number of permutations which could be originally Iahub's important permutation, modulo 1000000007 (109 + 7).

Input

The first line contains integer n (2 ≤ n ≤ 2000). On the second line, there are n integers, representing Iahub's important permutation after Iahubina replaces some values with -1.

It's guaranteed that there are no fixed points in the given permutation. Also, the given sequence contains at least two numbers -1 and each positive number occurs in the sequence at most once. It's guaranteed that there is at least one suitable permutation.

Output

Output a single integer, the number of ways Iahub could recover his permutation, modulo 1000000007 (109 + 7).

Sample test(s)
input
5
-1 -1 4 3 -1
output
2
Note

For the first test example there are two permutations with no fixed points are [2, 5, 4, 3, 1] and [5, 1, 4, 3, 2]. Any other permutation would have at least one fixed point.

有一个序列,要求你将其中的-1换成1到n中的一个数,使得其成为1到n的一个排列,但要求第i为不得放i,问有几种替换的方法。

分析:

一个典型的错排问题,考虑到有部分数其本身的位置已被摆放,但其本身还没有用到,即这部分数是无限制的排列。

有一部分数是其本身的位置还是-1,但其本身已被使用,这些数的数目与上一种数必定是相同的,这类数已被放置,也无需考虑。

有一部分数是其本身的位置已被摆放,其本身也已被使用,故这类数不会对排列产生影响,也不必考虑。

剩下一部分数是其本身的位置还是-1,其本身也还未被用到,即这一部分的数是有限制的排列。

从而,我们只需要第一类数和第四类数。

假设摆放j个有限制排列的数时的方法为dp[j],设总共有tx个无限制的数。

1.把一个有限制的数摆放到无限制的数所对应的tx个位置上时。。。仔细想想,这就相当于把一个无限制的数摆放到有限制的数的位置,则原来的那个有限制的数变成了无限制的数,即有限制的数减少了1,而无限制的数的数目不变,则有tx*dp[j-1]种。

2.把一个有限制的数摆放到j-1个有限制的数位置上时,且a[i]=j,a[j]=i;则共有(j-1)*dp[j-2]。

3.把一个有限制的数摆放到j-1个个有限制的数位置上时,且a[i]=j,a[j]!=i;则共有(j-1)*dp[j-1]。

所以dp[j]=tx*dp[j-1]+(j-1)*dp[j-2]+(j-1)*dp[j-1];

然后,在把剩下的tx个摆好,就是tx的阶乘。

然后,就没然后了,就AC了。。。

======================

当然这道题也可以用容斥做,考虑a[i]==i的个数,总数去掉这些就是答案了。

 //#####################
//Author:fraud
//Blog: http://www.cnblogs.com/fraud/
//#####################
#include <iostream>
#include <sstream>
#include <ios>
#include <iomanip>
#include <functional>
#include <algorithm>
#include <vector>
#include <string>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <climits>
#include <cctype>
using namespace std;
#define XINF INT_MAX
#define INF 0x3FFFFFFF
#define MP(X,Y) make_pair(X,Y)
#define PB(X) push_back(X)
#define REP(X,N) for(int X=0;X<N;X++)
#define REP2(X,L,R) for(int X=L;X<=R;X++)
#define DEP(X,R,L) for(int X=R;X>=L;X--)
#define CLR(A,X) memset(A,X,sizeof(A))
#define IT iterator
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<PII> VII;
typedef vector<int> VI;
const ll MOD = ;
int a[];
ll b[];
bool vis[];
ll dp[];
int main()
{
ios::sync_with_stdio(false);
int n;
cin>>n;
b[]=;
for(int i=;i<=n;i++)cin>>a[i];
for(ll i=;i<;i++)b[i]=(b[i-]*i)%MOD;
int tx=,ty=;
for(int i=;i<=n;i++){
if(a[i]!=-)vis[a[i]]=;
}
for(int i=;i<=n;i++){
if(a[i]==-){
if(vis[i])tx++;
else ty++;
}
}
dp[]=;
dp[]=tx*dp[]%MOD;
for(int i=;i<=ty;i++){
dp[i]=(tx*dp[i-]%MOD+(i-)*dp[i-]%MOD+(i-)*dp[i-]%MOD)%MOD;
}
cout<<dp[ty]*b[tx]%MOD<<endl; return ;
}

代码君

codeforces 340E Iahub and Permutations(错排or容斥)的更多相关文章

  1. CodeForces 340E Iahub and Permutations 错排dp

    Iahub and Permutations 题解: 令 cnt1 为可以没有限制位的填充数字个数. 令 cnt2 为有限制位的填充数字个数. 那么:对于cnt1来说, 他的值是cnt1! 然后我们对 ...

  2. HDU 1465 不容易系列之一 (错排公式+容斥)

    题目链接 Problem Description 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了! 做好"一件"事情尚且不易,若想永远成功而总从不失败,那更是难上 ...

  3. CodeForces 340E Iahub and Permutations

    容斥原理,组合数. 找出有$cnt$个数字还有没放,那么总方案数就是$cnt!$. 总方案数里面包含了正确的和非正确的,我们需要将非正确的删去. 先删去$1$个数字$a[i]=i$的情况,发现会多删, ...

  4. 【CF285E】Positions in Permutations(动态规划,容斥)

    [CF285E]Positions in Permutations(动态规划,容斥) 题面 CF 洛谷 题解 首先发现恰好很不好算,所以转成至少,这样子只需要确定完一部分数之后剩下随意补. 然后套一个 ...

  5. codeforces 341C Iahub and Permutations(组合数dp)

    C. Iahub and Permutations time limit per test 1 second memory limit per test 256 megabytes input sta ...

  6. CF285 E Positions in Permutations——“恰好->大于”的容斥和允许“随意放”的dp

    题目:http://codeforces.com/contest/285/problem/E 是2018.7.31的一场考试的题,当时没做出来. 题解:http://www.cnblogs.com/y ...

  7. codeforces 439 E. Devu and Birthday Celebration 组合数学 容斥定理

    题意: q个询问,每一个询问给出2个数sum,n 1 <= q <= 10^5, 1 <= n <= sum <= 10^5 对于每一个询问,求满足下列条件的数组的方案数 ...

  8. Codeforces 838A - Binary Blocks(二维前缀和+容斥)

    838A - Binary Blocks 思路:求一下前缀和,然后就能很快算出每一小正方块中1的个数了,0的个数等于k*k减去1的个数,两个的最小值就是要加进答案的值. 代码: #include< ...

  9. Codeforces 585E. Present for Vitalik the Philatelist(容斥)

    好题!学习了好多 写法①: 先求出gcd不为1的集合的数量,显然我们可以从大到小枚举计算每种gcd的方案(其实也是容斥),或者可以直接枚举gcd然后容斥(比如最大值是6就用2^cnt[2]-1+3^c ...

随机推荐

  1. 慕课linux学习笔记(八)常用命令(5)

    解压缩命令 常用压缩格式 .zip .gz .bz2 .tar.gz .tar.bz2 zip [压缩文件名] [ 原文件 ] #压缩文件 -r [压缩文件名] [ 源目录] #压缩目录 -r [压缩 ...

  2. MyISAM 存储引擎

    在MYSQL 5.1 以及之前的版本,MyISAM 是默认的存储引擎.MyISAM 提供了大量的特性,包括全文索引,压缩,空间函数(gis)等,但是MyISAM不支持事务和行级锁,而且有一个毫无疑问的 ...

  3. hadoop中datanode无法启动

    一.问题描述 当我多次格式化文件系统时,如 [hadoop@xsh hadoop]$ ./bin/hdfs namenode -format 会出现datanode无法启动,查看日志(/usr/loc ...

  4. WP Super Cache 安装与设置方法

    1.首先,永久连接不能使用默认格式 2.修改永久链接格式,中文推荐采用 /%post_id%.html (这下你知道我的.orz哪里来了吧) 如果你和我一样蛋疼愿意为每篇文章写一个英语的post sl ...

  5. curl 基本使用简介

    curl是Linux下一个非常著名的下载库,通过这个库,可以很简单的实现文件的下载等操作.看一个简单的例子: #include <curl/curl.h> #include <std ...

  6. SVN - 详细文档

    1.首先打开Cornerstone 2.然后如下图所示: 3.选择对应的仓库,如下图所示 4.然后Import完成之后,就把本地的文件提交到SVN服务器上了,如下图所示,另外如果你想要使用SVN进行版 ...

  7. 去掉Eclipse打开后定期弹出Usage Data Upload对话框

    Eclipse 的 UDC 老定期蹦出来说要上传使用数据到 eclipse 官网服务器去除方法: 1.删除 eclipse/plugins 目录下以 org.eclipse.epp.usagedata ...

  8. LeetCode_Path Sum II

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...

  9. android的原理--为什么我们不需要手动关闭程序

    内容搜集自网络,有所删改       不用在意剩余内存的大小,其实很多人都是把使用其他系统的习惯带过来来了.android大多应用没有退出的设计其实是有道理的,这和系统对进程的调度机制有关系.如果你知 ...

  10. RAID,mdadm(笔记)

    RAID: 级别:仅代表磁盘组织方式不同,没有上下之分:0: 条带    性能提升: 读,写    冗余能力(容错能力): 无    空间利用率:nS    至少2块盘1: 镜像    性能表现:写性 ...