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 }