[HDU 1394]Minimum Inversion Number(归并排序/线段树)
来源:互联网 发布:学数据库之前学什么 编辑:程序博客网 时间:2024/06/05 09:23
Description
The inversion number of a given number sequence a1, a2, …, an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.
For a given sequence of numbers a1, a2, …, an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:
a1, a2, …, an-1, an (where m = 0 - the initial seqence)
a2, a3, …, an, a1 (where m = 1)
a3, a4, …, an, a1, a2 (where m = 2)
…
an, a1, a2, …, an-1 (where m = n-1)
You are asked to write a program to find the minimum inversion number out of the above sequences.
Input
The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
Output
For each case, output the minimum inversion number on a single line.
Sample Input
10
1 3 6 9 0 8 5 7 4 2
Sample Output
16
Solution
先求这个排列的逆序对
然后每次把最前面的数字a[i]放到最后对之前求出的逆序对数inv的影响是inv=inv-a[i]+(n-1-a[i]) 因为比a[i]大的数有(n-1-a[i])个,比a[i]小的数有a[i]个
主要研究一下怎么nlogn求逆序对(数据太水了 其实暴力也能过)
归并排序
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int a[5005],n,tmp[5005],inv,Min,num[5005];void mergesort(int l,int r){ if(l>=r)return; int mid=(l+r)/2; mergesort(l,mid); mergesort(mid+1,r); int i=l,j=mid+1,k=l; while(i<=mid&&j<=r) { if(a[i]<=a[j]) { tmp[k]=a[i]; i++;k++; } else { inv+=mid-i+1; tmp[k]=a[j]; j++;k++; } } while(i<=mid) { tmp[k]=a[i]; k++;i++; } while(j<=r) { tmp[k]=a[j]; k++;j++; } i=l; while(i<=r) { a[i]=tmp[i]; i++; }}int main(){ while(scanf("%d",&n)==1) { inv=0; for(int i=1;i<=n;i++) { scanf("%d",&a[i]); num[i]=a[i]; } mergesort(1,n); Min=inv; for(int m=1;m<n;m++) { inv=inv-num[m]+n-1-num[m]; if(Min>inv)Min=inv; } printf("%d\n",Min); } return 0;}
线段树
用线段树维护每个数字出现过没有
每插入一个,查询比它大的数字出现了几个
#include<iostream>#include<cstdio>#include<cstring>#define MAXN 5000using namespace std;int a[MAXN+5],n,inv,Min,res;struct Node{ int l,r,num;}segt[MAXN*4];void build(int idx,int a,int b){ segt[idx].l=a; segt[idx].r=b; segt[idx].num=0; if(a==b)return; build(idx*2,a,(a+b)/2); build(idx*2+1,(a+b)/2+1,b);}void add(int idx,int a){ segt[idx].num++; if(segt[idx].l==segt[idx].r)return; int mid=(segt[idx].l+segt[idx].r)/2; if(a<=mid)add(idx*2,a); else add(idx*2+1,a);}void query(int idx,int a,int b){ if(segt[idx].l>=a&&segt[idx].r<=b) { res+=segt[idx].num; return; } int mid=(segt[idx].l+segt[idx].r)/2; if(b<=mid)query(idx*2,a,b); else if(a>mid)query(idx*2+1,a,b); else { query(idx*2,a,b); query(idx*2+1,a,b); }}int main(){ while(scanf("%d",&n)==1) { inv=0; build(1,0,n-1); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); add(1,a[i]); res=0; if(a[i]!=n-1) query(1,a[i]+1,n-1); inv+=res; } Min=inv; for(int m=1;m<n;m++) { inv=inv-a[m]+n-1-a[m]; if(Min>inv)Min=inv; } printf("%d\n",Min); } return 0;}
树状数组
树状数组也可以的 但是没写
- HDU 1394 Minimum Inversion Number( 归并排序 & 线段树 )
- [HDU 1394]Minimum Inversion Number(归并排序/线段树)
- HDU 1394 Minimum Inversion Number【线段树&&归并排序】
- HDU 1394 Minimum Inversion Number(线段树/归并排序求逆序对数)
- HDU 1394 Minimum Inversion Number(求逆序对+线段树||归并排序)
- hdu 1394 Minimum Inversion Number(线段树)【归并排序模板】
- HDU-1394-Minimum Inversion Number(暴力||归并排序||线段树||树状数组)
- hdu 1394 Minimum Inversion Number 逆序数 线段树&归并排序
- HDU 1394 Minimum Inversion Number【线段树,归并排序,树状数组】
- HDU 1394 Minimum Inversion Number(循环数组求逆序数)(暴力,归并排序,线段树)
- 杭电1394 Minimum Inversion Number(线段树+归并排序解法)
- (hdu1394)Minimum Inversion Number (树状数组/线段树/归并排序)
- HDU 1394 Minimum Inversion Number 线段树
- HDU 1394 Minimum Inversion Number 线段树
- HDU-1394 Minimum Inversion Number(线段树)
- 【线段树】hdu 1394 Minimum Inversion Number
- hdu 1394 Minimum Inversion Number 线段树
- hdu 1394 Minimum Inversion Number 线段树
- 蓝桥杯-寻找数列中最大数
- Qt入门之基础篇 ( 二 ) :Qt项目建立、编译、运行和发布过程解析
- [ZJOI2006书架]Splay
- 选项卡的实现的几种方法
- 如何踏上人工智能之路(机器学习篇)
- [HDU 1394]Minimum Inversion Number(归并排序/线段树)
- [MYSQL]如何并发查询并更新
- TCP/IP:UDP(3) ICMP
- leetcode 35. Search Insert Position
- [翻译]memcached 文本协议(未完成)
- 数据存储(SharedPreferences)(内部存储及外部存储)
- quagga源码学习--BGP协议对等体连接tcp md5签名认证选项
- C++最大公约数
- 1056. Mice and Rice (25)PAT甲级