zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第三场)E Two Matchings

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

    题解:

    这个题目我觉得也有点难,主要是难以想到就dp 4和6。

    首先 (p_i!=i \,\,and \,\,p_{pi}=i) 可得如果 (p_x=i) ,那么 (p_i=x)

    所以再来看这个要求的式子:((sum_{i=1}^{n}abs(a_i-a_{pi}))/2)

    可以知道一定存在 (a_i=a_{pi})(a_{pi}-a_i) ,把这个2消去,所以最后就变成了对于这n个数,找到 (frac{n}{2}) 对数之差最小,要找到两个这样的,并且这两个不能有任意一对相同。

    image-20200720211621393

    最后就是观察出来,要么拆成6,要么拆成4,最后dp一下。

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    #define debug(x) printf("debug:%s=%lld
    ",#x,x);
    //#define debug(x) cout << #x << ": " << x << endl
    using namespace std;
    const int maxn = 2e6+10;
    typedef long long ll;
    ll pre1[maxn],pre2[maxn];
    ll dp[maxn],a[maxn];
    int main(){
        int t;
        scanf("%d",&t);
        while(t--){
            int n;
            scanf("%d",&n);
            for(int i=1;i<=n;i++) dp[i]=inf64,scanf("%lld",&a[i]);
            sort(a+1,a+1+n);
            dp[0]=0;
            for(int i=1;i<=n;i+=2) dp[0]+=a[i+1]-a[i];
            for(int i=4;i<=n;i++) pre1[i]=a[i]+a[i-1]-a[i-2]-a[i-3];
            for(int i=6;i<=n;i++) pre2[i]=a[i]+a[i-1]+a[i-3]-a[i-2]-a[i-4]-a[i-5];
            for(int i=4;i<=n;i++){
                if(i>=4) dp[i]=min(dp[i],dp[i-4]+pre1[i]);
                if(i>=6) dp[i]=min(dp[i],dp[i-6]+pre2[i]);
            }
            printf("%lld
    ",dp[n]);
        }
    }
    
    
    
  • 相关阅读:
    静态代理模式
    反射+抽象工厂
    抽象工厂模式
    工厂方法模式
    简单工厂模式
    单例模式
    博客总览
    Bootstrap快速上手 --作品展示站点
    Java 网络编程---分布式文件协同编辑器设计与实现
    如何在博客园的博客中添加可运行的JS(转载)
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13347926.html
Copyright © 2011-2022 走看看