题解:本题主要考查贪心+逆序对
简要题意:一个序列移成一个前一段单调不降,后一段单调不升的序列最少要交换多少次 。
1.贪心:先把序列从大到小排序,最大值放在中间,次高的在左边或右边谁逆序对少就在哪边。
2.逆序对:对于一个数列下标1…n,把它进行操作后得到的下标为241…那么交换次数即为这个新数列的逆序对数。
3树状数组:求逆序对
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int num,h;
}a[7346278];
int tree[2342345];
long long n,m,ans=0,now=1;
int cmp(node a,node b)
{
return a.h>b.h;
}
int lowbit(int k)
{
return k&-k;
}
void add(int x,int k)
{
while(x<=n)
{
tree[x]+=k;
x+=lowbit(x);
}
}
int search(int x)
{
int ans=0;
while(x>0)
{
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i].h;
a[i].num=i;
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(a[i].h!=a[i-1].h)
for(;now<i;now++)add(a[now].num,1);
m=search(a[i].num);
ans+=min(now-1-m,m);
}
cout<<ans;
return 0;
}