hdu Minimum Inversion Number 的三种方法,暴力,线段树

来源:互联网 发布:ps软件破解版下载 编辑:程序博客网 时间:2024/05/16 07:28

 

暴力:

 

#include<stdio.h>#include<string.h>int a[5003];int main(){int i,j,n,sum;while(scanf("%d",&n)!=EOF){sum = 0;for(i=1;i<=n;i++) {scanf("%d",a+i);for(j=1;j<i;j++) if(a[j]>a[i]) sum++;}int ans = sum;for(i=1;i<=n;i++){sum += (-a[i] + n - a[i] - 1); //公式:第一个数移到最后位置后逆序数if(sum<ans) ans = sum;}printf("%d\n",ans);}return 0;}


线段树。

#include<stdio.h>#include<string.h>#define N 5010int s[N];struct node{int L;int R;int sum;}list[N*4];void build(int k,int x,int y){list[k].L = x;list[k].R = y;list[k].sum = 0;if(x==y) return;int mid = (x+y)>>1;build(k<<1,x,mid);build(k<<1|1,mid+1,y);}int finds(int k,int x,int y){if(list[k].L == x && list[k].R == y)return list[k].sum ;int mid = (list[k].L + list[k].R )>>1;if(x<=mid && y<=mid) return finds(k<<1,x,y);else if(x>mid && y>mid) return finds(k<<1|1,x,y);else return finds(k<<1,x,mid) + finds(k<<1|1,mid+1,y);}void update(int k,int key){list[k].sum ++;if(list[k].L == list[k].R) return;int mid = (list[k].L + list[k].R ) >> 1;if(key<=mid) update(k<<1,key);else update (k<<1|1,key);}int main(){int n,i,t,ans;while(scanf("%d",&n)!=EOF){ans = 0;build(1,0,n-1);for(i=0;i<n;i++){scanf("%d",&s[i]);ans += finds(1,s[i],n-1);update(1,s[i]);}t = ans;for(i=0;i<n-1;i++){t = t + (n-1-s[i]) - s[i];if(ans>t) ans = t;}printf("%d\n",ans);}return 0;}


这道题的主要是,后面的那个公式,让我再写一遍,ans += (n-1-a[i])-a[i];