码迷,mamicode.com
首页 > 其他好文 > 详细

错排公式

时间:2019-10-05 22:21:32      阅读:614      评论:0      收藏:0      [点我收藏+]

标签:NPU   reg   ora   view   open   比较   code   void   amp   


错排公式

d[n]=(n-1)*(d[n-1]+d[n-2])

模版题:

lgP1595 信封问题

题目描述

某人写了n封信和n个信封,如果所有的信都装错了信封。求所有信都装错信封共有多少种不同情况。

输入格式

一个信封数n(n<=20)

输出格式

一个整数,代表有多少种情况。

输入输出样例

输入 #1
2
输出 #1
1
输入 #2
3
输出 #2
2
 

第一次估计错误 喜提60
(话说字体为什么变了鸭)

long long long is too long for GCC

代码如下
技术图片
 1 #include<bits/stdc++.h>
 2 #define re register int
 3 #define LL long long 
 4 #define maxn 20+5 
 5 
 6 using namespace std;
 7 int n; 
 8 LL d[maxn]; 
 9 int main()
10 {
11     ios::sync_with_stdio(false);
12     cin>>n;
13     d[2]=1;
14     for(re i=3;i<=n;i++)
15     d[i]=(i-1)*(d[i-1]+d[i-2]);
16     cout<<d[n];
17  } 
View Code

 


UVA11481 Arrange the Numbers

 

愉快地复制在luogu写的题解(题解这东西没必要写两遍嘛)

前置知识:错排公式 (好吧知不知道错排公式不是很重要)

题意:

给出n,m,k,求n个数的排列满足前m个数中恰好有k个数不是错排的方案数。

多组输入输出,数据组数t满足:1<=t<=5.


m个数钦定k个数在正确的位置上的方案数是: $C_{m}^{k}$

因为要求恰好k个数不是错排,那么剩下n-k个数中前m-k个数必定是错排。

设f[i][j]为i个数,前j个数必须是错排的方案数。

则f[i][0]=i!

f[i][j]=f[i][j-1]-f[i-1][j-1]

i个数前j个必为错排的方案数==i个数前j-1个数必为错排的方案数-i个数前j-1个数必为错排&&第j个数是j的方案数

因为第j个数已经钦定 所以(i个数前j-1个数必为错排的方案数&&第j个数==j的方案数)==i-1个数前j-1个数必为错排的方案数 

细节见代码


技术图片
 1 #include<bits/stdc++.h>
 2 #define re register int
 3 #define maxn 1000+5
 4 #define LL long long
 5 #define mod 1000000007
 6 
 7 using namespace std;
 8 int t,n,m,k;
 9 LL c[maxn][maxn];
10 LL f[maxn][maxn];//f[i][j]表示i位数前j位错排的方案数 
11 void pre()
12 {
13     for(re i=0;i<=1000;i++)
14     c[i][0]=1;//c[0][0]也设1 不然乘的时候会爆炸233333 
15     for(re i=1;i<=1000;i++)
16     for(re j=1;j<=i;j++)
17     c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
18     f[0][0]=1;//不初始化成1 f[1][1]&&f[1][0]会出错
19     //当然f[1][1]会出错比较重要 
20     for(re i=1;i<=1000;i++)
21     f[i][0]=(f[i-1][0]*i)%mod;
22     for(re i=1;i<=1000;i++)
23     for(re j=1;j<=i;j++)
24     f[i][j]=((f[i][j-1]-f[i-1][j-1])%mod+mod)%mod;
25     //i个数前j个必为错排的方案数==i个数前j-1个数必为错排的方案数-i个数前j-1个数必为错排&&第j个数是j的方案数
26 
27     //因为第j个数已经钦定 所以(i个数前j-1个数必为错排的方案数&&第j个数==j的方案数)==i-1个数前j-1个数必为错排的方案数 
28 }
29 int main()
30 {
31     ios::sync_with_stdio(false);
32     cin>>t;
33     pre();
34     for(re i=1;i<=t;i++) 
35     {
36         cin>>n>>m>>k;
37         LL  ans=(c[m][k]*f[n-k][m-k])%mod;
38         cout<<"Case"<<" "<<i<<": "<<ans<<endl; 
39     }
40     return 0;
41 }
View Code

 

 

错排公式

标签:NPU   reg   ora   view   open   比较   code   void   amp   

原文地址:https://www.cnblogs.com/3200Pheathon/p/11625647.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!