• 2020牛客暑期多校训练营(第三场)E


    题目链接:Two Matchings

    题意:给你一个序列a,你要找到两种完全不同的整个序列的两两匹配,使得所有两两匹配差的绝对值的和最小,输出这个和

    思路:对序列a排序后,显然最小的匹配相邻两两匹配,即$(a_2-a_1)+(a_4-a_3)+dots+(a_n - a_{n-1})$,关键在如何求第二小的匹配

    对于第二小的匹配,我们可以讲整个序列分为多个4个数的子序列和多个6个数的子序列

    对于4个数的子序列,除了相邻两两匹配外,第二小的匹配为$a_3+a_4-a_2-a_1$

    对于6个数的子序列,除了相邻两两匹配外,第二小的匹配为$a_6+a_5+a_3-a_4-a_1-a_2$

    对于偶数位进行dp即可,即dp[i]=min(dp[i - 4] + a[i] + a[i - 1] - a[i - 2] - a[i - 3],dp[i - 6] + a[i] + a[i - 1] + a[i - 3] - a[i - 5] - a[i - 4] - a[i - 2])

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    
    const int N = 200010;
    const ll INF = 1000000000000000000;
    
    int T, n;
    ll a[N], dp[N];
    
    int main()
    {
        // freopen("in.txt", "r", stdin);
        // freopen("out.txt", "w", stdout);
        scanf("%d", &T);
        while (T--) {
            scanf("%d", &n);
            for (int i = 1; i <= n; i++) dp[i] = INF;
            for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
            sort(a + 1, a + n + 1);
            ll res = 0;
            for (int i = 1; i <= n; i += 2) res = res + a[i + 1] - a[i];
            if (n == 4) {
                printf("%lld
    ", a[4] + a[3] - a[2] - a[1] + res);
                continue;
            }
            dp[4] = a[4] + a[3] - a[2] - a[1];
            dp[6] = a[6] + a[5] + a[3] - a[1] - a[2] - a[4];
            for (int i = 8; i <= n; i += 2) {
                ll t1 = dp[i - 4] + a[i] + a[i - 1] - a[i - 2] - a[i - 3];
                ll t2 = dp[i - 6] + a[i] + a[i - 1] + a[i - 3] - a[i - 5] - a[i - 4] - a[i - 2];
                dp[i] = min(t1, t2);
            }
            printf("%lld
    ", dp[n] + res);
        }
        return 0;
    }
  • 相关阅读:
    线程学习笔记(一)
    进程间通信
    管道通信操作
    在程序中执行shell命令
    进程控制(一)
    Makefile文件学习总结
    进程学习笔记
    C#不安全代码和指针
    Unity3D ShaderLab 修改渲染队列进行深度排序
    Unity3D ShaderLab 透明裁剪着色器
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/13341823.html
Copyright © 2020-2023  润新知