zoukankan      html  css  js  c++  java
  • 【题解】SCOI2008配对

    贪心+dp~观察数据,发现一个规律:将数字排序之后,最优匹配只可能产生在该数字和与它距离不超过二的数字之间。

    所以可以用dp[i]代表前i个数(排序)匹配的最小差值,之后暴力选出该新数应该如何匹配。

    以及题目保证A[i](B[i])中所有数字互不相同,这是为了避免一种情况的出现:

    1 1 5 5

    5 5 1 1

    此时的最优解距离就超过了二啦。这种情况我并没有想到解,也很好奇是不是能够有接受这种情况的算法。

    以下我丑丑的代码……(捂脸)、+INF要开大大大大大大大大大!

    #include <bits/stdc++.h>
    using namespace std;
    #define maxn 2500000
    #define INF 9999999999LL
    #define int long long
    int dp[maxn], a[maxn], b[maxn], n, mark[maxn], cnt[maxn];
    
    int read()
    {
        int x = 0;
        char c;
        c = getchar();
        while(c < '0' || c > '9') c = getchar();
        while(c >='0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x;
    }
    
    int abs(int x, int y)
    {
        if(x == y) return INF;
        else return (x - y) >= 0 ? x - y : y - x;
    }
    
    signed main()
    {
        n = read();
        for(int i = 1; i <= n; i ++) 
            a[i] = read(), b[i] = read();
        for(int i = 1; i <= n; i ++) dp[i] = INF;
        sort(a + 1, a + 1 + n);
        sort(b + 1, b + 1 + n);
        for(int i = 1; i <= n; i ++)
        {
            mark[i] += mark[i - 1];
            if(a[i] == a[i - 1]) cnt[i] = cnt[i - 1] + 1;
            else cnt[i] = 1;
            if(a[i] == b[i]) mark[i] ++;
            if(a[i] != b[i]) dp[i] = dp[i - 1] + abs(a[i], b[i]);
            if(i >= 2)
            {
                if(a[i] != a[i - 1]) 
                    dp[i] = min(dp[i - 2] + abs(a[i], b[i - 1]) + abs(b[i], a[i - 1]), dp[i]);
                if(i >= 3 && mark[i] - mark[i - 3] >= 2)
                {
                    int tem = abs(a[i], b[i - 2]) + abs(a[i - 1], b[i]) + abs(a[i - 2], b[i - 1]);
                    tem = min(tem, abs(a[i], b[i - 1]) + abs(a[i - 1], b[i - 2]) + abs(a[i - 2], b[i]));
                    tem = min(tem, abs(a[i], b[i - 2]) + abs(a[i - 1], b[i - 1]) + abs(a[i - 2], b[i]));
                    dp[i] = min(dp[i], dp[i - 3] + tem);
                }
            }
        }
        if(dp[n] >= INF) printf("-1
    ");
        else printf("%lld
    ", dp[n]);
        return 0;
    }
  • 相关阅读:
    第2章 创建基础框架
    目录
    工厂方法模式(Factory Method)
    petshop4.0 详解之七(PetShop表示层设计)
    第1章 启动电子商务网站
    第3章 创建商品目录:第Ⅰ部分
    编写一个JAVA应用程序,用户从键盘只能输入整数,程序输出这些整数的乘积
    书上例题练习第一章
    java与C/C++的区别
    安装JDK遇到的问题
  • 原文地址:https://www.cnblogs.com/twilight-sx/p/8407637.html
Copyright © 2011-2022 走看看