HDU 1394 - Minimum Inversion Number(BIT)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1394
【题意】
已知一个数列,数列长度,范围在,并且不重复,也就是说是一个的排列。每次可以将数列的第一个数移动到最后面,这样可以构造出个数列。求这个数列中的最小逆序数。
【思路】
只需要求出初始序列的逆序对个数,剩下的 个序列的逆序对个数可以递推出来,假设现在数列的第一个数是 ,那么后面有 个元素比 小,剩下个元素比大,这样原来会有个逆序对产生,如果把移动到数列最后,那么原来的个逆序对会消失,新产生个逆序对,所以每次移动一个元素时,会额外产生个逆序对
#include<bits/stdc++.h>
using namespace std;
const int maxn=5005;
int n;
int a[maxn];
int bit[maxn];
void add(int i,int x){
while(i<=n){
bit[i]+=x;
i+=i&-i;
}
}
int sum(int i){
int ans=0;
while(i){
ans+=bit[i];
i-=i&-i;
}
return ans;
}
int main(){
while(scanf("%d",&n)==1 && n){
for(int i=0;i<n;++i) scanf("%d",&a[i]);
memset(bit,0,sizeof(bit));
int inv=0;
for(int i=0;i<n;++i){
inv+=sum(n)-sum(a[i]+1);
add(a[i]+1,1);
}
int ans=inv;
for(int i=0;i<n-1;++i){
inv+=n-1-a[i]*2;
ans=min(ans,inv);
}
printf("%d\n",ans);
}
return 0;
}