• BNU 4096 逆序 思维题


    https://www.bnuoj.com/v3/problem_show.php?pid=4096

    对于一个序列a,我们定义它的逆序数为满足a[i]>a[j]且i<j的有序对<i,j>的个数,这样的有序对称为逆序对。

    例如 a[0]=1,a[1]=2,a[2]=4,a[3]=5,a[4]=3,存在的逆序对就有<2,4>和<3,4>,其逆序数就是2。

    现在,给你一个长为N的序列,要求恰好执行K次交换操作,每次交换只能在相邻的两个数之间进行,问得到的结果序列其逆序数最小和最大可能是多少。

     

    Input

     输入数据有多组,每组数据包括两行,第一行有两个整数N (1<=N<=1,000)和K(0<=K<=1,000,000,000),分别是序列的长度和需要执行的交换操作的次数。

    第二行有N个整数,依次给出了序列中的所有数,都在int范围内。

    输入以EOF结束。

     

    Output

     对于每组数据,单独输出一行,包括两个整数,以一个空格隔开,第一个为执行恰好K次操作后得到的最小逆序值,第二个为最大逆序值。

     

    Sample Input

    5 1
    1 2 3 4 5
    5 1
    1 2 3 5 4

    Sample Output

    1 1
    0 2

    Source

    Author

    Huang Kun @ BNU (modified from HUST campus)
     
    这个关键在于想到
    1、有重复数字
    2、逆序对数目最大不一定是 n * (n - 1) / 2的,因为有重复数字的话,2、2、2这样的数据,就是0
     
    我的思路是先求出一开始的逆序对数目,然后和k比较,因为它能移k次,按照最优的方案来说,每次都能增加/减去1个逆序对数目。
    所以判断下当前有多少个逆序对now + k 和mx的关系即可
     
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    int n, k;
    const int maxn = 1000 + 20;
    int a[maxn];
    int b[maxn];
    map<int, int>book;
    int calc(int a[]) {
        int ans = 0;
        for (int i = 1; i <= n; ++i) {
            for (int j = i + 1; j <= n; ++j) {
                if (a[i] > a[j]) ++ans;
            }
        }
        return ans;
    }
    bool cmp(int a, int b) {
        return a > b;
    }
    void work() {
        int bug = 0;
        book.clear();
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &a[i]);
            b[i] = a[i];
            if (book[a[i]]) bug = 1;
            book[a[i]]++;
        }
        int now = calc(a);
        sort(a + 1, a + 1 + n, cmp);
        int mx = calc(a);
        int ansmi = 0;
        int ansmx = 0;
        int mxcut = 0, miadd = 0;
        if (n == 1) {
            printf("0 0
    ");
            return;
        }
        if (now + k <= mx) {
            ansmx = now + k;
        } else {
            ansmx = mx;
            int left = now + k - mx;
            if (left % 2 == 1 && !bug) mxcut = 1;
        }
        if (now - k >= 0) {
            ansmi = now - k;
        } else {
            ansmi = 0;
            int left = k - now;
            if (left % 2 == 1 && !bug) miadd = 1;
        }
        printf("%d %d
    ", ansmi + miadd, ansmx - mxcut);
    }
    
    int main() {
    #ifdef local
        freopen("data.txt","r",stdin);
    #endif
        while (scanf("%d%d", &n, &k) != EOF) work();
        return 0;
    }
    View Code
  • 相关阅读:
    iOS13使用bluetooth作为peripheral发送广播问题
    替代AttributeString的一个Label的类目
    Xcode拖动选中代码
    判断地图定位授权状态
    QLPreViewController的初步实用
    iOS的多版本配置(版本分离,多环境配置)
    -[NSBundle initWithURL:]: nil URL argument'
    xib的UIScrollView自适应高度
    ab工具-压力测试工具
    UIImageView的属性contentMode
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6009499.html
Copyright © 2020-2023  润新知