C - Insertion Sort 沈阳区域赛 打表找规律
现有一段函数,要求输入一个数组A和一个k,进行一次题目给出的冒泡模仿插入 进行k次。
问给你三个数,n,k,mod,你在1-n的全排列中,有多少个序列运行这个函数之后其最长上升子序列的长度大于等于(n-1),最后的结果对mod取模。
然后 我们上下做差 能看出是等差数列
首项是 i∗i!i * i!i∗i!,然后差是 2∗i!2 * i!2∗i!
那么 对应第 k 列 n 行 来说 它就是 k!+k! +k!+ 等差数列的和
这样开始化简公式
矩阵 对角线 是 K! 我们差 也是从这里开始的 之后就是细心推了 //看上图
打表代码如下:
1 #include<bits/stdc++.h> 2 #include<string> 3 #include<cstring> 4 #include<stdio.h> 5 using namespace std; 6 # define ll long long 7 # define inf 0x3f3f3f3f 8 const int maxn =1000; 9 int a[maxn]; 10 int vis[maxn]; 11 int ww[maxn][maxn]; 12 int b[maxn]; 13 bool judge(int t,int w) 14 { 15 for(int i=1; i<=t; i++){ 16 b[i]=a[i]; 17 } 18 sort(b+1,b+w+1); 19 memset(vis,0,sizeof(vis)); 20 int ans=0; 21 int temp; 22 for(int i=t; i>=1; i--){ 23 temp=1; 24 int maxx=0; 25 for(int j=i; j<=t; j++){ 26 if(b[j]>b[i]){ 27 maxx=max(maxx,vis[j]); 28 } 29 } 30 vis[i]=maxx+1; 31 } 32 for(int i=1; i<=t; i++) 33 { 34 if(vis[i]>=t-1)return true; 35 } 36 return false; 37 } 38 int main() 39 { 40 int t=10; 41 while(1){ 42 if(t==0)break; 43 for(int i=1; i<=t; i++){ 44 a[i]=i; 45 } 46 do{ 47 for(int i=1; i<=t; i++){ 48 if(judge(t,i)){ 49 ww[t][i]++; 50 } 51 } 52 } while(next_permutation(a+1,a+t+1)); 53 t--; 54 } 55 for(int i=1; i<=10; i++) 56 { 57 58 for(int j=1; j<=i; j++) 59 { 60 cout<<ww[i][j]<<" "; 61 } 62 cout<<endl; 63 } 64 return 0; 65 }
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define int long long 4 typedef long long ll; 5 6 int n, m , mod; 7 8 signed main() { 9 int cas; 10 int tt = 1; 11 cin >> cas; 12 while(cas --) { 13 cin >> n >> m >> mod; 14 int k = 1; 15 if(m >= n - 1) m = n; 16 for(int i = 2; i <= m; i ++) { 17 k *= i % mod; 18 k %= mod; 19 } 20 cout << "Case #" << tt ++ << ": " ; 21 if(m >= n - 1) cout << k << endl; 22 else cout << (k)*(n * n % mod - (m + 1) * n % mod + m + 1 + mod) % mod << endl; 23 } 24 return 0; 25 }