codeforces 340E Iahub and Permutations(错排or容斥)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
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).
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 a single integer, the number of ways Iahub could recover his permutation, modulo 1000000007 (109 + 7).
5
-1 -1 4 3 -1
2
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容斥)的更多相关文章
- CodeForces 340E Iahub and Permutations 错排dp
Iahub and Permutations 题解: 令 cnt1 为可以没有限制位的填充数字个数. 令 cnt2 为有限制位的填充数字个数. 那么:对于cnt1来说, 他的值是cnt1! 然后我们对 ...
- HDU 1465 不容易系列之一 (错排公式+容斥)
题目链接 Problem Description 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了! 做好"一件"事情尚且不易,若想永远成功而总从不失败,那更是难上 ...
- CodeForces 340E Iahub and Permutations
容斥原理,组合数. 找出有$cnt$个数字还有没放,那么总方案数就是$cnt!$. 总方案数里面包含了正确的和非正确的,我们需要将非正确的删去. 先删去$1$个数字$a[i]=i$的情况,发现会多删, ...
- 【CF285E】Positions in Permutations(动态规划,容斥)
[CF285E]Positions in Permutations(动态规划,容斥) 题面 CF 洛谷 题解 首先发现恰好很不好算,所以转成至少,这样子只需要确定完一部分数之后剩下随意补. 然后套一个 ...
- codeforces 341C Iahub and Permutations(组合数dp)
C. Iahub and Permutations time limit per test 1 second memory limit per test 256 megabytes input sta ...
- CF285 E Positions in Permutations——“恰好->大于”的容斥和允许“随意放”的dp
题目:http://codeforces.com/contest/285/problem/E 是2018.7.31的一场考试的题,当时没做出来. 题解:http://www.cnblogs.com/y ...
- codeforces 439 E. Devu and Birthday Celebration 组合数学 容斥定理
题意: q个询问,每一个询问给出2个数sum,n 1 <= q <= 10^5, 1 <= n <= sum <= 10^5 对于每一个询问,求满足下列条件的数组的方案数 ...
- Codeforces 838A - Binary Blocks(二维前缀和+容斥)
838A - Binary Blocks 思路:求一下前缀和,然后就能很快算出每一小正方块中1的个数了,0的个数等于k*k减去1的个数,两个的最小值就是要加进答案的值. 代码: #include< ...
- Codeforces 585E. Present for Vitalik the Philatelist(容斥)
好题!学习了好多 写法①: 先求出gcd不为1的集合的数量,显然我们可以从大到小枚举计算每种gcd的方案(其实也是容斥),或者可以直接枚举gcd然后容斥(比如最大值是6就用2^cnt[2]-1+3^c ...
随机推荐
- String类的使用说明
(1)Length()取一个字符串的长度:public int length(); public calss StringLength1{ public static void main(String ...
- xen之基本搭建
1. 前言 所需包: kernel-xen xen xen-libs (xen依赖包) xen_runtime (xen依赖包) 以上xen包需要版本号一致,例如4.1.3版本,这里使用xm接口管理工 ...
- 序列!序列!- 零基础入门学习Python016
序列!序列! 让编程改变世界 Change the world by program 你可能发现了,小甲鱼把列表.元组和字符串放在一块儿来讲解是有道理的,我们发现Ta们之间有很多共同点: 1. 都可以 ...
- HDU Today--hdu2112
HDU Today Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- Hibernate整合Struts2时报错
今天在整合Hibernate和Struts2的时候遇到一个问题 总是出现各种异常,经过仔细检查,代码本身并没有问题, ----------------------------------------- ...
- Keil 中关于C语言编译生成汇编代码函数名规则
在keil 中 C语言的函数有带参数和不带参数之分. 一般的资料里说fun(void)类型的函数不带参数,所以,keil编译器生成的汇编的调用地址(函数名) 为fun.这没有错.事实上,不管C语言的函 ...
- The square chest
The square chest Sophia pressed the button in front of her, slamming her fist against it. The door r ...
- 【转】如何测试CTS4.0 -- 不错
原文网址:http://blog.csdn.net/subsist/article/details/7209341/ CTS4.0测试步骤 V1.2 (更新到CTS4.0 R3) 第一:平台准 ...
- MicrosoftSQLServer中的锁模式
在SQL Server数据库中加锁时,除了可以对不同的资源加锁,还可以使用不同程度的加锁方式,即锁有多种模式,SQL Server中锁模式包括: 1.共享锁 SQL Server中,共享锁用于所有的只 ...
- C# 判断两个日期是否是同一天
System.Data.Entity.DbFunctions.DiffDays(cs.StartTime.Value,DateTime.Now) == 0//只获取当天 OR XX.StartTime ...