• BZOJ1237: [SCOI2008]配对


    题意:给定两个数组 构造一个配对 使得每个位置上之差的和最小 大小相同的不能配对

    题解:猜了一下 应该把两个数组排序一下 答案最小

       处理相同的不能配对的时候 那么应该找就近的交换

       猜一下 如果有合法方案的话 肯定一个大小为3的环就能解决配对问题了

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll INF = 1e12;
     
    int q[100005];
    int w[100005];
    ll dp[100005];
     
    ll abss(ll x, ll y)
    {
        if(x == y) return INF;
        else if(x > y) return x - y;
        else if(x < y) return y - x;
    }
     
    int main()
    {
        dp[0] = 0;
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%d%d", &q[i], &w[i]), dp[i] = INF;
        sort(q + 1, q + 1 + n);
        sort(w + 1, w + 1 + n);
     
        for(int i = 1; i <= n; i++)
        {
            if(i >= 1 && dp[i - 1] != INF)
            {
                //if(i == 3) cout<<"hi"<<endl;
                ll x = abss(q[i], w[i]);
                dp[i] = min(dp[i], dp[i - 1] + x);
                //if(i == 3) cout<<dp[i]<<endl;
            }
            if(i >= 2 && dp[i - 2] != INF)
            {
                ll x1 = abss(q[i], w[i - 1]);
                ll x2 = abss(q[i - 1], w[i]);
                dp[i] = min(dp[i], dp[i - 2] + x1 + x2);
                //if(i == 3) cout<<dp[i]<<endl;
            }
            if(i >= 3 && dp[i - 3] != INF)
            {
                ll x1 = abss(q[i], w[i - 2]);
                ll y1 = abss(q[i - 1], w[i - 1]);
                ll y2 = abss(q[i - 2], w[i]);
                dp[i] = min(dp[i], dp[i - 3] + y1 + y2 + x1);
     
                ll z1 = abss(q[i - 1], w[i]);
                ll z2 = abss(q[i - 2], w[i - 1]);
                dp[i] = min(dp[i], dp[i - 3] + z1 + z2 + x1);
     
                ll o1 = abss(q[i], w[i - 1]);
                ll o2 = abss(q[i - 1], w[i - 2]);
                ll o3 = abss(q[i - 2], w[i]);
                dp[i] = min(dp[i], dp[i - 3] + o1 + o2 + o3);
                //if(i == 3) cout<<dp[i]<<endl;
            }
        }
        //for(int i = 1; i <= n; i++) cout<<dp[i]<<endl;
     
        if(dp[n] == INF) puts("-1");
        else printf("%lld
    ", dp[n]);
        return 0;
    }
    View Code
  • 相关阅读:
    结队完成-连续最大子数组和
    一、数据库的基础简介
    十六、Shell之expect自动化交互程
    十五、Shell之数组
    十四、循环控制
    十三、Shell之select语句
    Linux系统产生随机数的6种方法
    十二、Shell之for循环
    十一、Shell之while&&until循环
    Shell补充之后台执行脚本程序
  • 原文地址:https://www.cnblogs.com/lwqq3/p/9740867.html
Copyright © 2020-2023  润新知