暴力:
#include<stdio.h>
#include<string.h>
int a[5003];
int main()
{
int i,j,n,sum;
while(scanf("%d",&n)!=EOF)
{
sum = 0;
for(i=1;i<=n;i++)
{
scanf("%d",a+i);
for(j=1;j<i;j++) if(a[j]>a[i]) sum++;
}
int ans = sum;
for(i=1;i<=n;i++)
{
sum += (-a[i] + n - a[i] - 1); //公式:第一个数移到最后位置后逆序数
if(sum<ans) ans = sum;
}
printf("%d\n",ans);
}
return 0;
}
线段树。
#include<stdio.h>
#include<string.h>
#define N 5010
int s[N];
struct node
{
int L;
int R;
int sum;
}list[N*4];
void build(int k,int x,int y)
{
list[k].L = x;
list[k].R = y;
list[k].sum = 0;
if(x==y) return;
int mid = (x+y)>>1;
build(k<<1,x,mid);
build(k<<1|1,mid+1,y);
}
int finds(int k,int x,int y)
{
if(list[k].L == x && list[k].R == y)
return list[k].sum ;
int mid = (list[k].L + list[k].R )>>1;
if(x<=mid && y<=mid) return finds(k<<1,x,y);
else if(x>mid && y>mid) return finds(k<<1|1,x,y);
else return finds(k<<1,x,mid) + finds(k<<1|1,mid+1,y);
}
void update(int k,int key)
{
list[k].sum ++;
if(list[k].L == list[k].R) return;
int mid = (list[k].L + list[k].R ) >> 1;
if(key<=mid) update(k<<1,key);
else update (k<<1|1,key);
}
int main()
{
int n,i,t,ans;
while(scanf("%d",&n)!=EOF)
{
ans = 0;
build(1,0,n-1);
for(i=0;i<n;i++)
{
scanf("%d",&s[i]);
ans += finds(1,s[i],n-1);
update(1,s[i]);
}
t = ans;
for(i=0;i<n-1;i++)
{
t = t + (n-1-s[i]) - s[i];
if(ans>t) ans = t;
}
printf("%d\n",ans);
}
return 0;
}
这道题的主要是,后面的那个公式,让我再写一遍,ans += (n-1-a[i])-a[i];