题目:http://acm.hdu.edu.cn/showproblem.php?pid=1394
可以暴力。。
也可以用线段树优化。。用线段树就是查找比当前这个数大的已存入线段树中的个数。比如求a[i],那么就查找当前线段树(a[i]+1,n)中的个数。。然后把a[i]更新到线段树中。。
下面是AC代码:
#include<iostream>
#include<cstdio>
using namespace std;
#define N 5002
struct node
{
int l,m,r;
int num;
} trie[N*4];
int a[5001];
void creat(int id,int beg,int end)
{
trie[id].l=beg;
trie[id].r=end;
trie[id].num=0;
trie[id].m=(beg+end)>>1;
if(beg<end)
{
creat(id*2,trie[id].l,trie[id].m);
creat(id*2+1,trie[id].m+1,trie[id].r);
}
}
void update(int id,int l,int r)
{
if(trie[id].l==l&&trie[id].r==r)
{
trie[id].num+=1;
return ;
}
else
{
if(trie[id].m>=l)
update(id*2,l,r); //在左子树
else
update(id*2+1,l,r); //在右子树
}
trie[id].num=trie[id*2].num+trie[id*2+1].num;
}
int find(int id,int beg,int end)
{
if(trie[id].l==beg&&trie[id].r==end)
{
return trie[id].num;
}
else
{
if(trie[id].m>=end)
{
return find(id*2, beg,end);
}
else if(trie[id].m<beg)
{
return find(id*2+1,beg,end);
}
else
{
return find(id*2,beg,trie[id].m)+find(id*2+1,trie[id].m+1,end);
}
}
}
int main()
{
int n;
while(cin>>n)
{
creat(1,1,n);
int sum=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
a[i]++;
}
for(int i=1; i<=n; i++)
{
if(a[i]+1<=n)
sum+=find(1,a[i]+1,n);
update(1,a[i],a[i]);
// cout<<sum<<endl;
}
int ans=sum;
for(int i=1; i<=n-1; i++)
{
sum=sum+(n-a[i])-(a[i]-1);
if(sum<ans) ans = sum;
}
cout<<ans<<endl;
}
return 0;
}