1. 程式人生 > 實用技巧 >CF362C Insertion Sort(字首和)

CF362C Insertion Sort(字首和)

給出一個長度為NN的無序序列,序列為00到N-1N1的排列,現在需要你用氣泡排序來將序列排成從小到大有序的序列

你可以執行一次交換兩個元素i,j(i\neq j,1\le i\leq n)i,j(i=j,1in),使得執行氣泡排序時,交換相鄰元素的次數最少

要你求出交換相鄰元素的最少次數和滿足交換相鄰元素的次數最少的方案數

題解:

#include<bits/stdc++.h>
using namespace std;
const int maxn=5005;
int n;
int a[maxn];
int l[maxn][maxn];
//l(i,j)表示前j個數裡大於數字i的個數 
int r[maxn][maxn]; //r(i,j)表示前j個數裡小於數字j的個數 int main () { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d",a+i),a[i]++; for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) { if (a[j]>i) l[i][j]=l[i][j-1]+1; else l[i][j]
=l[i][j-1]; if (a[j]<i) r[i][j]=r[i][j-1]+1; else r[i][j]=r[i][j-1]; } } int num=0; for (int i=1;i<=n;i++) num+=l[a[i]][i]; int Min=num; for (int i=1;i<=n;i++) { for (int j=i+1;j<=n;j++) {
int t1=l[a[j]][j-1]-l[a[j]][i]; int t2=l[a[i]][j-1]-l[a[i]][i]; int t3=r[a[j]][j-1]-r[a[j]][i]; int t4=r[a[i]][j-1]-r[a[i]][i]; Min=min(Min,num-t1+t2+t3-t4+(a[i]<a[j]?1:-1)); } } int ans=0; for (int i=1;i<=n;i++) { for (int j=i+1;j<=n;j++) { int t1=l[a[j]][j-1]-l[a[j]][i]; int t2=l[a[i]][j-1]-l[a[i]][i]; int t3=r[a[j]][j-1]-r[a[j]][i]; int t4=r[a[i]][j-1]-r[a[i]][i]; if (Min==num-t1+t2+t3-t4+(a[i]<a[j]?1:-1)) ans++; } } printf("%d %d\n",Min,ans); }