Codeforces 888D Almost Identity Permutations:錯排公式

Leohh發表於2018-02-25

題目連結: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 }

 

相關文章