给一个0..n-1的排列
每次可以把第一个移到最后一个,求最小的逆序对数
首先用树状数组来搞出修改前的逆序对,倒着扫,求在第i的数之前有多少个比它小的数已经被插入进树里。
假设当前放在第一个的值值是a[i],放在最后会减少 a[i]个逆序对,同时会增加 n-1-a[i]-1+1个逆序对 所以逆序对每次改变为n-2*a[i]-1
扫一般就好了
#include<bits/stdc++.h>
using namespace std;
int n;
int a[10000];
void Gao()
{
for (int i=1;i<=n;i++)
scanf("%d",a+i);
Tree.clear();
int ans=0;
for (int i=n;i>=1;i--)
{
ans+=Tree.getsum(a[i]);
Tree.modify(a[i],1);
}
int tem=ans;
for (int i=1;i<=n;i++)
tem+=n-2*a[i]-1,ans=min(ans,tem);
cout<<ans<<endl;
}
int main()
{
//freopen("a.in","r",stdin);
while (cin>>n)
Gao();
return 0;
}