题目链接: Insertion Sort
大致题意:
给一个只排前k项的排序算法
问一个以1 − n为元素的数组有多少种排列方式能在这个排序算法完成之后能使最长上升子序列的长度达到n − 1
解题思路:
1.k>=n时的答案为n !
2.k < n时,后面的n − k个数要么保持有序要么可以把任意一个数放到另外一个数的位置上,贡献为( 1 + ( n − k ) ∗ ( n − k − 1 ) ) ∗ k !
如果前k 个元素不是1 − k ,想要满足题意也只能是从后面的n − k 个数中挑一个数插到前k 个位置的某一位置上,贡献为( n − k ) ∗ k ∗ k !
AC代码:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= n; ++i)
using namespace std;
typedef long long ll;
int main()
{
int t;cin>>t;
for(int i=1;i<=t;++i){
ll n,m,k;
ll res=1;
cin>>n>>k>>m;
for(int j=2;j<=k;++j){
res=res*j%m;
}
if(k>=n){
ll ress = 1;
for (int j = 1; j <= n; ++j) ress = ress * j % m;
printf("Case #%d: %lld\n",i,ress);
}
else {
res=res*(1+(n-k)*(n-k-1)+(n-k)*k)%m;
printf("Case #%d: %lld\n",i,res);
}
}
return 0;
}