• AcWing 1215. 小朋友排队(树状数组)


    n 个小朋友站成一排。

    现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。

    每个小朋友都有一个不高兴的程度。

    开始的时候,所有小朋友的不高兴程度都是 0。

    如果某个小朋友第一次被要求交换,则他的不高兴程度增加 1,如果第二次要求他交换,则他的不高兴程度增加 2(即不高兴程度为 3),依次类推。当要求某个小朋友第 k 次交换时,他的不高兴程度增加 k。

    请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。

    如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。

    输入格式

    输入的第一行包含一个整数 n,表示小朋友的个数。

    第二行包含 n 个整数 H1,H2,…,Hn,分别表示每个小朋友的身高。

    输出格式

    输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。

    数据范围

    1≤n≤100000,
    0≤Hi≤1000000

    输入样例:

    3
    3 2 1
    

    输出样例:

    9
    

    样例解释

    首先交换身高为3和2的小朋友,再交换身高为3和1的小朋友,再交换身高为2和1的小朋友,每个小朋友的不高兴程度都是3,总和为9。

    1 5 2 4 3 6

    1 2 5 4 3 6

    1 2 4 5 3 6

    1 2 4 3 5 6

    1 2 3 4 5 6

    1 2 5 3 4 6

    首先题目要求相邻交换=有序,可以看出来是进行类似冒泡排序的操作。要求不高兴度最低就是要找到最优解。然后我们发现对于每个小朋友,不高兴度是固定下来的,即交换次数是固定的。联想到逆序对,每个小朋友的交换次数就是在他前面比他高的小朋友的个数k1加上在他后面比他矮的小朋友的个数k2(由于身高一样肯定选择不换,因此要严格高or严格矮)。逆序对求解可以两次树状数组统计。最后用等差数列公式累加一遍答案即可。

    #include <iostream>
    #include <cstring>
    #define N 1000005
    using namespace std;
    int n, h[N];
    int c[N] = { 0 };
    int lft[N], rht[N];
    void add(int x, int y)
    {
        for (; x <= N; x += (x & -x)) c[x] += y;
    }
    int ask(int x)
    {
        int ans = 0;
        for (; x; x -= (x & -x)) ans += c[x];
        return ans;
    }
    int main()
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> h[i];
        for (int i = 1; i <= n; i++)
        {
            lft[i] = ask(N) - ask(h[i]);
            add(h[i], 1);
        }
        memset(c, 0, sizeof(c));
        for (int i = n; i >= 1; i--)
        {
            rht[i] = ask(h[i] - 1);
            add(h[i], 1);
        }
        long long ans = 0;
        for (int i = 1; i <= n; i++)
        {
            //cout << lft[i] << ' ' << rht[i] << endl;
            ans += 1ll * (1ll + lft[i] + rht[i]) * (lft[i] + rht[i]) / 2;
        }
        cout << ans;
    }
    
  • 相关阅读:
    linux学习 建立静态库,动态库,写简单的makefile
    C++中顶层const和底层const
    BDB (Berkeley DB)数据库简单介绍(转载)
    Java中Map的使用
    Spring MVC 3 深入总结
    nvl,空时的推断和取值
    java堆栈 (转)
    mybatis--面向接口编程
    HDU 4888
    socket编程——一个简单的样例
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/13955683.html
Copyright © 2020-2023  润新知