zoukankan      html  css  js  c++  java
  • hdu 4911 Inversion(归并排序求逆序对数)2014多校训练第5场

    Inversion

                                                                                Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

    Problem Description
    bobo has a sequence a1,a2,…,an. He is allowed to swap two adjacent numbers for no more than k times.

    Find the minimum number of inversions after his swaps.

    Note: The number of inversions is the number of pair (i,j) where 1≤i<j≤n and ai>aj.
     

    Input
    The input consists of several tests. For each tests:

    The first line contains 2 integers n,k (1≤n≤105,0≤k≤109). The second line contains n integers a1,a2,…,an (0≤ai≤109).
     

    Output
    For each tests:

    A single integer denotes the minimum number of inversions.
     

    Sample Input
    3 1 2 2 1 3 0 2 2 1
     

    Sample Output
    1 2
     
    题意:给出n个数,每次能够交换相邻的两个数。最多交换k次,求交换后最小的逆序数是多少。

    分析:假设逆序数大于0。则存在1 ≤ i < n,使得交换ai和ai+1后逆序数减1。所以最后的答案就是max((inversion-k), 0)。

    利用归并排序求出原序列的逆序对数就能够解决这个问题了。

    #include<stdio.h>
    #include<string.h>
    #define N 100005
    __int64 cnt, k;
    int a[N],c[N];
    //归并排序的合并操作
    void merge(int a[], int first, int mid, int last, int c[])
    {
        int i = first, j = mid + 1;
        int m = mid, n = last;
        int k = 0;
        while(i <= m || j <= n)
        {
            if(j > n || (i <= m && a[i] <= a[j]))
                c[k++] = a[i++];
            else
            {
                c[k++] = a[j++];
                cnt += (m - i + 1);
            }
        }
        for(i = 0; i < k; i++)
            a[first + i] = c[i];
    }
    //归并排序的递归分解和合并
    void merge_sort(int a[], int first, int last, int c[])
    {
        if(first < last)
        {
            int mid = (first + last) / 2;
            merge_sort(a, first, mid, c);
            merge_sort(a, mid+1, last, c);
            merge(a, first, mid, last, c);
        }
    }
    int main()
    {
        int n;
        while(~scanf("%d%I64d",&n,&k))
        {
            memset(c, 0, sizeof(c));
            cnt = 0;
            for(int i = 0; i < n; i++)
                scanf("%d", &a[i]);
            merge_sort(a, 0, n-1, c);
            if(k >= cnt) cnt = 0;
            else cnt -= k;
            printf("%I64d
    ",cnt);
        }
    }
     
  • 相关阅读:
    latch与DFF
    数字逻辑综合DC脚本示例及解释
    当DiscuzNT遇上了Loadrunner(下)
    [C#学习]在多线程中如何调用Winform
    并发性测试工具
    当DiscuzNT遇上了Loadrunner(上)
    大型网站(高访问、海量数据)技术架构
    Load Runner下载
    Invoke 和 BeginInvoke 的真正涵义
    当DiscuzNT遇上了Loadrunner(中)
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5340836.html
Copyright © 2011-2022 走看看