Codeforces 888D Almost Identity Permutations:错排公式

题目链接:http://codeforces.com/problemset/problem/888/D

题意:

  给定n,k,问你有多少种1到n的排列,满足至少有n-k个a[i] == i。

  (4 <= n <= 1000, 1 <= k <= 4)

 

题解:

  转换题意:

    给定n,k,问你有多少种1到n的排列,满足最多有k个a[i] != i。

  D(i)表示1到i的排列的错排方案数。

  那么ans = ∑(C(n,i) * D(i)) + 1,其中i∈[2,k]。

  ps:

    错排递推式:D(n) = (n-1) * (D(i-1)+D(i-2))

    错排通项式:D(n) = n! * ∑(((-1)^i) / i!),其中i∈[2,n]

 

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 
 5 using namespace std;
 6 
 7 long long n,k;
 8 long long ans=1;
 9 
10 int main()
11 {
12     cin>>n>>k;
13     if(k>=2) ans+=n*(n-1)/2;
14     if(k>=3) ans+=2*n*(n-1)*(n-2)/6;
15     if(k>=4) ans+=9*n*(n-1)*(n-2)*(n-3)/24;
16     cout<<ans<<endl;
17 }

 

posted @ 2018-02-25 12:44  Leohh  阅读(385)  评论(0编辑  收藏  举报