读题的时候要仔细一点,n个数字,问在有至少(n-k)个数字序号与值对应的情况下,有多少种不同的排列。换言之就是有n个数字,求从k到1的错排(前面再乘一个组合数)。要注意是至少……所以后面对k讨论的时候每种情况都是+。
这里涉及到一个全错位排列的知识点,也就是所有的数字都不在原来的位置。
比较小的几个错排数:
D1= 0,D2= 1,D3=2,D4= 9,D5= 44,D6= 265,D7= 1854
#include <iostream>
#include <cstdio>
using namespace std;
#define ll long long
ll n, k;//n(4,1000) k(1,4)
ll ans;
/*ll jc(int x){
if(x == 1 || x == 0) return 1;
return x*jc(x-1);
}*/
ll getC(ll n, ll i){
//ll tans = jc(n) / (jc(n-i)*jc(i));
if(i == 2)
return n*(n-1) / 2;
if(i == 3)
return n*(n-1)*(n-2) / 6;
if(i == 4)
return n*(n-1)*(n-2)*(n-3) / 24;
//return tans;
return 1;
}
//D1= 0,D2= 1,D3=2,D4= 9,D5= 44,D6= 265,D7= 1854
int main() {
scanf("%lld%lld", &n, &k);
ans = 0;
if(k>=1){
ans += 1;
}
if(k>=2){
ans += getC(n, 2);
}
if(k>=3){
ans += 2*1ll*getC(n, 3);
}
if(k>=4){
ans += 9*1ll*getC(n, 4);
}
printf("%lld\n", ans);
return 0;
}
/** 是有6种排列,但是并不是全错排
k = 3
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
**/