Minimum Inversion Number
http://acm.hdu.edu.cn/showproblem.php?pid=1394
题意:
n个数经过移动n个产生n个序列,每个序列都记录该序列中满足反转数的总个数,求这n个序列中最小的反转数的个数
思路:
这一题的关键是n-a[i]-(a[i]-1)这行代码
n-a[i]:第一个数字从第一个移到最后一个之后,其他n-1个数字他们增加反转数的个数
a[i]-1:移动之前这个数满足反转数的个数
代码:
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; typedef long long ll; const int maxn = 5050; int bit[maxn],a[maxn]; int n; inline ll min(ll a,ll b){ return a<b?a:b; } int lowbit(int x){ return x&(-x); } ll sum(int x){ ll ans=0; while(x){ ans+=bit[x]; x-=lowbit(x); } return ans; } void query(int x){ while(x<=n){ bit[x]++; x+=lowbit(x); } } int main(){ while(scanf("%d",&n)!=EOF){ memset(bit,0,sizeof(bit)); ll ans = 0; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); a[i]++; ans += sum(n)-sum(a[i]); query(a[i]); } ll mm = ans; for(int i=1;i<=n;i++){ mm +=n-a[i]-(a[i]-1); ans = min(ans,mm); } cout<<ans<<endl; } return 0; }