HDU_1394_Minimum Inversion Number
给定一组数,然后依次的挪动该组数的元素共得到n种序列。求这n中序列中逆序数最少的个数。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<string> #include<queue> using namespace std; #define N 5005 int n,c[N]; int sum(int x) { int ret=0; while(x) { ret+=c[x]; x-=x&-x; } return ret; } void add(int x) { while(x<=n) { c[x]++; x+=x&-x; } } int main() { int a[N],i,j,k; while(~scanf("%d",&n)) { memset(c,0,sizeof(c)); int ans=0; for(i=1;i<=n;++i) { scanf("%d",&a[i]); a[i]++;//a[i]从0开始,而树状数组下标从1开始,所以自增1 add(a[i]); ans+=(i-sum(a[i])); //求得的逆序对 } int Min=ans; /*从后往前看,把a[n]移到第一位,逆序对增加a[i]-1,逆序对减少n-a[i]*/ for(i=n;i>1;--i) { ans+=2*a[i]-1-n; Min=min(ans,Min); } printf("%d\n",Min); } return 0; }