• 奇技淫巧训练之八


    https://www.luogu.org/problem/P2507

    分析:

    首先看到这道题一定不会是什么高级算法,肯定是贪心啊dp啊

    先考虑ai可以等于bi,则直接排序即可

    但是ai!=bi的,怎么办?

    读题!!!

    上帝给你关了一道门一定会再给你开一扇窗de

    a数组和b数组内部元素是不等的

    • 所以需要交换
    • 此时交换的范围越小,绝对值和越小

    我们贪心的想到,因为每个数顶多在a,b中各出现一次

    所以当某次ai=bi时,则ai!=b(i-1),ai!=b(i+1)

    因为是绝对值,你不知道ai-b(i-1)和b(i+1)-ai谁更大

    所以要取个最小

    • a1-b1
    • a1-b2,a2-b1(两两交换)
    • a1-b2,a2-b3,a3-b1(3个之间的交换)
    • a1-b3,a2-b1,a3-b2(3个之间的交换)

    这时你会想问

    这样不会重复吗?

    考虑吧a(i-1),ai,a(i+1)变为ai,a(i+1),a(i+2),于是就线性推过去dp,是不会重复的

    如果还是不清楚的话,见代码就会明白了

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int N=100005;
    const long long M=1e13;
    int a[N],b[N],n;
    long long f[N],ans;
    
    long long Min(long long a,long long b)
    {
    if (a<b) return a;
    return b;
    }
    long long js(int l,int r)
    {
    if (a[l]==b[r]) return M;
    return abs(a[l]-b[r]);
    }
    int main()
    {
    scanf("%d",&n);
    for (int i=1; i<=n; i++) scanf("%d%d",&a[i],&b[i]);
    sort(a+1,a+n+1);
    sort(b+1,b+n+1);
    if (n==1&&a[1]==b[1]) printf("-1
    ");
    else
    {
        f[0]=0;
        for (int i=1; i<=n; i++)
        {
            ans=M;
            if (i>=1) ans=Min(ans,f[i-1]+js(i,i)); 
            if (i>=2) ans=Min(ans,f[i-2]+js(i-1,i)+js(i,i-1));
            if (i>=3) 
            {
                ans=Min(ans,f[i-3]+js(i-2,i-1)+js(i-1,i)+js(i,i-2));
                ans=Min(ans,f[i-3]+js(i-2,i)+js(i-1,i-2)+js(i,i-1));
            } 
            f[i]=ans;
        }
        printf("%lld
    ",f[n]);
    }
    return 0;
    }
    
  • 相关阅读:
    C语言PRO2
    pro5
    自我介绍
    李喆第5次作业
    李喆的作业
    一个队列类的实现(比delphi自带的速度快70倍)
    关于 IHTMLDocument4 在 Delphi7.0 中不能编译的的解决方法
    高吞吐量的一个日志函数类_用于IOCP (Delphi)
    PostThreadMessage在线程中应用(以多线程网站数据采集为例)
    微软企业库5 加密篇
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/11689911.html
Copyright © 2020-2023  润新知