https://codeforces.com/gym/101955
C題
題意:輸入n,k,q,問有多少1~n的排列,使得在把前k個按升序排好序後,最長上升子序列的長度不低於n-1.
暴力打表找規律,得出方程。
打表代碼:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <iterator>
using namespace std;
int num;
int f[10],b[10];
void dfs(int a[], int k, int m, int w){
if (k==m) {
copy(a+1, a+m+1, b+1); //流迭代器
// copy(b+1, b+m+1, ostream_iterator<int>(cout, " ")); //流迭代器
// printf("\n");
sort(b+1,b+w+1);
for (int i=1; i<=m; i++) f[i]=1;
for (int i=2; i<=m; i++){
for (int j=i-1; j>=1; j--)
{
if (b[j]<b[i]){
if (f[i]<f[j]+1)
f[i]=f[j]+1;
}
}
}
// for (int i=1)
// copy(f+1, f+m+1, ostream_iterator<int>(cout, " ")); //流迭代器
// printf("\n");
for (int i=1; i<=m; i++){
if (f[i]>=m-1) {
num++;
break;
}
}
// copy(a+1, a+m+1, ostream_iterator<int>(cout, " ")); //流迭代器
}
for (int i = k; i <= m; i++)
{
int tmp=a[k]; a[k]=a[i]; a[i]=tmp;
dfs(a, k+1, m, w);
tmp=a[k],a[k]=a[i],a[i]=tmp;
}
}
int main()
{
int a[10];
for (int n=1; n<=5; n++){
printf("%d:",n);
for (int k=1; k<=n; k++){
for (int i = 1; i <= n; i++) a[i]=i;
num=0;
dfs(a, 1, n, k);
printf(" %d",num);
}
printf("\n");
}
return 0;
}
ac代碼:(注意特判k>n的情況,直接輸出n!)
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int _;
long long n,k,q;
scanf("%d",&_);
for (int u=1; u<=_; u++){
cin>>n>>k>>q;
long long ans=1;
if (k>n) {
for (long long i=1; i<=n; i++){
ans*=i;
ans%=q;
}
printf("Case #%d: %I64d\n",u,ans);
}
else {
for (long long i=1; i<=k; i++){
ans*=i;
ans%=q;
}
ans*=(1+k*(n-k)+(n-k)*(n-k-1));
ans%=q;
printf("Case #%d: %I64d\n",u,ans);
}
}
return 0;
}