题意:
输入一个长度 n
第二行给出长度为n的数组,数组的值刚好为0到n-1这n个数。
然后每次把数组的第一个数放到最后一个,放n-1次,共有n个排列,这n个排列就有n个逆序数,输出这n个逆序数的最小值。
我的做法:
1、每次输入a[i]后,都把a[i] ++;
2、求出第一个排列的逆序数
3、递推求出所有的逆序数
那怎么求1呢?
对于每一个a[i],求出1到i-1 中比它大的个数,然后相加,即可得。若用朴素的查找,肯定会超时的,所以这里就利用线段树或者树状数组来快速查找。
线段树版本:
1 #include<cstdio> 2 #include<cstring> 3 #define lson l,m,rt<<1 4 #define rson m+1,r,rt<<1|1 5 const int maxn=5010; 6 int c[maxn<<2]; 7 int a[maxn]; 8 int sum[maxn]; 9 void pushup(int rt) 10 { 11 c[rt]=c[rt<<1]+c[rt<<1|1]; 12 } 13 void update(int p,int add,int l,int r,int rt) 14 { 15 if(l==r){ 16 c[rt]+=add; 17 return; 18 } 19 int m=(l+r)>>1; 20 if(p<=m) 21 update(p,add,lson); 22 else 23 update(p,add,rson); 24 pushup(rt); 25 } 26 int query(int L,int R,int l,int r,int rt) 27 { 28 if(L<=l&&R>=r) 29 return c[rt]; 30 int m=(l+r)>>1; 31 int ret=0; 32 if(L<=m) 33 ret+=query(L,R,lson); 34 if(R>m) 35 ret+=query(L,R,rson); 36 return ret; 37 } 38 int main() 39 { 40 int n; 41 while(scanf("%d",&n)!=EOF){ 42 sum[1]=0; 43 memset(c,0,sizeof(c)); 44 for(int i=1;i<=n;i++){ 45 scanf("%d",&a[i]); 46 a[i]++; 47 sum[1]+=query(a[i],n,1,n,1); 48 update(a[i],1,1,n,1); 49 } 50 for(int i=2;i<=n;i++) 51 sum[i]=sum[i-1]+n+1-2*a[i-1]; 52 int ans=n*n; 53 for(int i=1;i<=n;i++) 54 if(sum[i]<ans) 55 ans=sum[i]; 56 printf("%d\n",ans); 57 } 58 return 0; 59 }
用了46ms
树状数组版本:
1 #include<cstdio> 2 #include<cstring> 3 const int maxn=5010; 4 int c[maxn]; 5 int a[maxn]; 6 int sum[maxn]; 7 int lowbit(int x) 8 { 9 return x&(-x); 10 } 11 void update(int x,int d,int n) 12 { 13 while(x<=n){ 14 c[x]+=d; 15 x+=lowbit(x); 16 } 17 } 18 int query(int x) 19 { 20 int ret=0; 21 while(x>0){ 22 ret+=c[x]; 23 x-=lowbit(x); 24 } 25 return ret; 26 } 27 int main() 28 { 29 int n; 30 while(scanf("%d",&n)!=EOF){ 31 memset(c,0,sizeof(c)); 32 sum[1]=0; 33 for(int i=1;i<=n;i++){ 34 scanf("%d",&a[i]); 35 a[i]++; 36 sum[1]+=(i-1-query(a[i])); 37 update(a[i],1,n); 38 } 39 for(int i=2;i<=n;i++) 40 sum[i]=sum[i-1]+n+1-2*a[i-1]; 41 int ans=n*n; 42 for(int i=1;i<=n;i++) 43 if(ans>sum[i]) 44 ans=sum[i]; 45 printf("%d\n",ans); 46 } 47 return 0; 48 }
也是46ms