我是靠谱客的博主 清秀毛巾,最近开发中收集的这篇文章主要介绍HDU 1394 Minimum Inversion Number (树状数组)Minimum Inversion Number,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Minimum Inversion Number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7975    Accepted Submission(s): 4889


Problem 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
 


 

 

题意:一个由0..n-1组成的序列,每次可以把队首的元素移到队尾,求形成的n个序列最小逆序对数目
算法:
由树状数组求逆序对。加入元素i即把以元素i为下标的a[i]值+1,从队尾到队首入队,
每次入队时逆序对数 += getsum(i - 1),即下标比它大的但是值比它小的元素个数。
因为树状数组不能处理下标为0的元素,每个元素进入时+1,相应的其他程序也要相应调整。
求出原始的序列的逆序对个数后每次把最前面的元素移到队尾,逆序对数即为

原逆序对数+比i大的元素个数-比i小的元素个数,因为是0..n,容易直接算出,每次更新min即可。


什么是树状数组: http://blog.csdn.net/deng_hui_long/article/details/11066851

 

import java.io.*;
import java.util.*;
/*
 *
 * author : deng_hui_long 
 * Date   : 2013-9-4
 *
*/
public class Main {
	int n,MAX=5010;
	int[] a=new int[MAX];
	int[] c=new int[MAX];
	
	public static void main(String[] args) {
		new Main().work();
	}
	
	
	void work(){
		Scanner sc=new Scanner(new BufferedInputStream(System.in));
		while(sc.hasNext()){
			
			n=sc.nextInt();
			Arrays.fill(c,0);
			for(int i=0;i<n;i++){
				a[i]=sc.nextInt();
			}
			
			int sum=0;
			for(int i=n-1;i>=0;i--){
				update(a[i]+1,1);
				sum+=getSum(a[i]);
			}

			int ans=sum;
			for(int i=0;i<n;i++){
				sum=sum-a[i]+n-1-a[i];
				ans=Math.min(ans, sum);
			}
			System.out.println(ans);
		}
		
	}
	
	
	int lowbit(int x){
		return x&(x^(x-1));
	}
	
	
	void update(int i,int x){
		while(i<=n){
			c[i]+=x;
			i+=lowbit(i);
		}
	}
	
	
	int getSum(int x){
		int sum=0;
		while(x>0){
			sum+=c[x];
			x-=lowbit(x);
		}
		return sum;
	}
}

 

 

import java.io.*;
import java.util.*;
/*
 *
 * author : deng_hui_long 
 * Date   : 2013-9-4
 *
*/
public class Main {
	int n,MAX=5010;
	int[] a=new int[MAX];
	int[] c=new int[MAX];
	
	public static void main(String[] args) {
		new Main().work();
	}
	
	
	void work(){
		Scanner sc=new Scanner(new BufferedInputStream(System.in));
		while(sc.hasNext()){
			
			n=sc.nextInt();
			Arrays.fill(c,0);
			for(int i=0;i<n;i++){
				a[i]=sc.nextInt();
			}
			
			int sum=0;
			//getsum(i),即下标比它大的但是值比它小的元素个数。
			//i-getsum(i),即下标比它大的但是值比它大的元素个数。
			for(int i=0;i<n;i++){
				update(a[i]+1,1);
				sum+=i-getSum(a[i]);//逆序对数+比i大的元素个数
			}

			int ans=sum;
			for(int i=0;i<n;i++){
				sum=sum-a[i]+n-1-a[i];
				ans=Math.min(ans, sum);
			}
			System.out.println(ans);
		}
		
	}
	
	
	int lowbit(int x){
		return x&(x^(x-1));
	}
	
	
	void update(int i,int x){
		while(i<=n){
			c[i]+=x;
			i+=lowbit(i);
		}
	}
	
	
	int getSum(int x){
		int sum=0;
		while(x>0){
			sum+=c[x];
			x-=lowbit(x);
		}
		return sum;
	}
}


import java.io.*;
import java.util.*;
/*
 *
 * author : deng_hui_long 
 * Date   : 2013-9-4
 *
*/
public class Main {
	int n,MAX=5010;
	int[] a=new int[MAX];
	int[] c=new int[MAX];
	int id;
	public static void main(String[] args) {
		new Main().work();
	}
	void work(){
		Scanner sc=new Scanner(new BufferedInputStream(System.in));
		while(sc.hasNext()){
			n=sc.nextInt();
			for(int i=0;i<n;i++){
				int k=sc.nextInt();
				a[i]=k;
			}
			Arrays.fill(c,0);
			int sum=0;
			for(int i=0;i<n;i++){
	            sum+=a[i]-getSum(a[i]);  
	            plus(a[i]+1,1);
			}
			int ans=sum;
			for(int i=0;i<n;i++){
				sum=sum-a[i]+n-1-a[i];
				ans=Math.min(ans, sum);
			}
			System.out.println(ans);
		}
	}

	int lowbit(int x){
		return x&(x^(x-1));
	}

	void plus(int i,int x){
		while(i<=n){
			c[i]+=x;
			i+=lowbit(i);
		}
	}

	int getSum(int x){
		int sum=0;
		while(x>0){
			sum+=c[x];
			x-=lowbit(x);
		}
		return sum;
	}
	
	class Node implements Comparable<Node>{
		int val;
		int num;
		public int compareTo(Node o) {
			
			return this.val>o.val?1:-1;
		}
	}
}



 

最后

以上就是清秀毛巾为你收集整理的HDU 1394 Minimum Inversion Number (树状数组)Minimum Inversion Number的全部内容,希望文章能够帮你解决HDU 1394 Minimum Inversion Number (树状数组)Minimum Inversion Number所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部