概述
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
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.
10 1 3 6 9 0 8 5 7 4 2
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所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复