• HDU 1394 Minimum Inversion Number


    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
     
    题意:一个长度为n的数列,可以变化为n个不同的数列(每次将首位元素放到最后一位),问这些序列中逆序数的个数最少为多少,逆序数:i < j and ai > aj,下标小于该元素的下标,值大于该元素。
     
    可以先利用线段树求出本身的序列中有多少逆序数,然后判断每个元素放到最后一位时的逆序个数是否小于本身序列的逆序个数,逐次更新。
     
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int N=5010;
    
    struct node
    {
        int left, right, num;
    }no[4*N];
    int Min;
    
    void Bulid(int left, int right, int root)
    {
        int mid;
    
        no[root].left = left;
        no[root].right = right;
        no[root].num = 0; 
    
        if (left == right) return ;
    
        mid = (left+right)/2;
    
        Bulid(left, mid, root*2);
        Bulid(mid+1, right, root*2+1);
    }
    
    void Insert(int p, int root) ///插入数据时就可以统计逆序数的个数
    {
        int mid;
    
        no[root].num++;
    
        if (no[root].left == no[root].right) return ;
    
        mid = (no[root].left+no[root].right)/2;
    
        if (p <= mid)
        {
            Min += no[root*2+1].num;
            Insert(p, root*2);
        }
        else Insert(p, root*2+1);
    }
    
    int main ()
    {
        int i, n, p[N], ans;
    
        while (scanf("%d", &n) != EOF)
        {
            Bulid(0, n-1, 1);
            Min = 0;
    
            for (i = 1; i <= n; i++)
            {
                scanf("%d", &p[i]);
                Insert(p[i], 1);
            }
    
            ans = Min;
    
            for (i = 1; i <= n; i++)
            {
                Min += (n-1-p[i]) - p[i]; ///首位移到最后一位时,逆序数加上那些比它大的数的个数,减去那些比它小的数的个数(因为该序列的元素都是0~n-1)
                ans = min(ans, Min);
            }
    
            printf("%d
    ", ans);
        }
    
        return 0;
    }
     
  • 相关阅读:
    iOS AFNetworking 2.6.0框架导入报错解决方法
    GitHub 上都有哪些值得关注学习的 iOS 开源项目?
    iOS开发ARC机制下的内存管理技术要点
    UIColor延伸:判断两个颜色是否相等
    iOS中的单例模式
    明天再整理,睡觉!
    pushViewController:animated:的问题
    解决UINavigationController在pushViewController时出现的"卡顿"问题
    在某OC字符串中,搜索指定的某字符串:-rangeOfString:
    SSH整合redis和MongoDB错误笔记
  • 原文地址:https://www.cnblogs.com/syhandll/p/4732602.html
Copyright © 2020-2023  润新知