bzoj 1237 配对

news/2024/7/23 10:03:47

Written with StackEdit.

Description

你有\(n\) 个整数\(A_i\)\(n\) 个整数\(B_i\)。你需要把它们配对,即每个\(A_i\)恰好对应一 个\(B_i\)。要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对。例如\(A=\){\(5,6,8\)},\(B=\){\(5,7,8\)},则最优配对方案是\(5\)\(8\), \(6\)\(5\), \(8\)\(7\),配对整数的差的绝对值分别为\(2, 2, 1\),和为\(5\)。注意,\(5\)\(5\)\(6\)\(7\)\(8\)\(8\)是不允许的,因 为相同的数不许配对。

Input

第一行为一个正整数\(n\),接下来是\(n\) 行,每行两个整数\(A_i\)\(B_i\),保证所有 \(A_i\)各不相同,\(B_i\)也各不相同

Output

输出一个整数,即配对整数的差的绝对值之和的最小值。如果无法配对,输 出\(-1\)

Sample Input

3
3 65
45 10
60 25

Sample Output

32

HINT

\(1 <= n <= 10^5\)\(A_i\)\(B_i\)均为\(1\)\(10^6\)之间的整数。

Solution

第一眼费用流 然而看数据范围 显然不可做...

  • 考虑先将\(A\)\(B\)从小到大排序.
  • 若没有相同的不可取的限制,显然直接贪心,\(A_i\)\(B_i\).
  • 注意到,\(A_i\)各不相同,\(B_i\)也各不相同.所以如果\(A_i=B_i\),那么\(A_i\)肯定与\(B_{i-1},B_{i-2}\)都不相同.
  • 这样容易发现,\(A_{i-2},A_{i-1},A_{i},B_{i-2},B_{i-1},B_{i}\)两两配对是一定有合法方案的.
  • \(f[i]\)表示将\(A_1\)\(A_i\),\(B_1\)\(B_i\)两两配对的最小花费.
  • 枚举,\(A_{i-2},A_{i-1},A_{i},B_{i-2},B_{i-1},B_{i}\)两两配对的方式转移即可.
  • 注意边界\(f[1],f[2].\)以及特判无解.
#include<bits/stdc++.h>
#define inf 1e18
using namespace std;
typedef long long LoveLive;
inline int read()
{
    int out=0,fh=1;
    char jp=getchar();
    while ((jp>'9'||jp<'0')&&jp!='-')
        jp=getchar();
    if (jp=='-')
        {
            fh=-1;
            jp=getchar();
        }
    while (jp>='0'&&jp<='9')
        {
            out=out*10+jp-'0';
            jp=getchar();
        }
    return out*fh;
}
const int MAXN=1e5+10;
int a[MAXN],b[MAXN];
inline LoveLive calc(int x,int y)
{
    return x==y?inf:abs(x-y);
}
inline void upd(LoveLive &x,LoveLive y)
{
    if(y<x)
        x=y;
}
int n;
LoveLive f[MAXN];
void init()
{
    f[0]=0;
    f[1]=calc(a[1],b[1]);
    f[2]=min(f[1]+calc(a[2],b[2]),calc(a[1],b[2])+calc(a[2],b[1]));
}
int main()
{
    n=read();
    for(int i=1;i<=n;++i)
        a[i]=read(),b[i]=read();
    if(n==1 && a[1]==b[1])
        {
            puts("-1");
            return 0;
        }
    sort(a+1,a+1+n);
    sort(b+1,b+1+n);
    init();
    for(int i=3;i<=n;++i)
        {
            f[i]=inf;
            upd(f[i],f[i-1]+calc(a[i],b[i]));
            upd(f[i],f[i-2]+calc(a[i-1],b[i])+calc(a[i],b[i-1]));
            upd(f[i],f[i-3]+calc(a[i],b[i-2])+calc(a[i-1],b[i-1])+calc(a[i-2],b[i]));
            upd(f[i],f[i-3]+calc(a[i],b[i-1])+calc(a[i-1],b[i-2])+calc(a[i-2],b[i]));
            upd(f[i],f[i-3]+calc(a[i],b[i-2])+calc(a[i-1],b[i])+calc(a[i-2],b[i-1]));
        }
    printf("%lld\n",f[n]);
    return 0;
}

开long long.

转载于:https://www.cnblogs.com/jklover/p/10063571.html


http://www.niftyadmin.cn/n/1050096.html

相关文章

9.6Html

Img width height 单位是px a 超链接 <a href””>百度一下</a> a 两个属性 一个是 href 值是需要跳转的页面地址 另一个是target跳转页面打开的方式 _blank _self(默认的) 备注 Id 是一种起名方式 id”zhangsan” 只要使用id起的名字 前面必须加# #zha…

虚拟机chrome os 没有可用网络错误

从http://chromeos.hexxeh.net/ 下载了一个chrome os的VM版本的&#xff0c;在VM9上打开运行&#xff0c;一直提示没有可用网络 解决方案 查看虚拟机的网络设置设置为 NAT方式查看主机电脑是否可以上网打开---chromeos虚拟机安装目录的 .vmx文件添加 ethernet0.virtualDev &qu…

测试用例实例

1、 一 个好的用例的表述要点&#xff0c;即用例中应当包含的信息 一个优秀的 测试 用例 &#xff0c;应该包含以下信息&#xff1a; 1&#xff09; 软 件或项目的名称 2&#xff09; 软件或项目的版本&#xff08;内部版本号&#xff09; 3&…

让TestDirector支持IE7/IE8

让TestDirector支持IE7/IE8(1)以系统管理员身份登录到TD服务器&#xff1b;(2)找到TD服务器中TDBIN目录&#xff08;缺省情况下是&#xff1a;C:/Inetpub/TDBIN目录&#xff09;&#xff0c;用编辑器打开start_a.htm文件&#xff1b; 注&#xff1a;start_a.htm也有可能在C:/I…

windows下安装msysgit 及ruby

一&#xff1a;安装msysgit git是目前最流行的软件版本控制软件&#xff0c;在window下通常使用msysgit 下载&#xff1a;http://msysgit.github.io/安装&#xff1a;基本上一路默认下一步就行安装之后&#xff0c;可以打开git bash二&#xff1a;安装ruby 目前我使用的是 ruby…

CentOS7:ifconfig command not found解决

问题描述 我是在VirtualBox上装的CentOS 7 Minimal&#xff0c;网上搜了一下原因&#xff0c;可能是CentOS 7的最小化安装少了一些工具&#xff0c;比如 ifconfig 及 netstat 等。因此解决办法很简单&#xff0c;把它们安装上就好了。 首先判断一下是不是缺少了ifconfig&#x…

索引介绍

一、索引的概念 索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。在书籍中&#xff0c;索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。在数据库中&#xff0c;索引也允许数据库程序迅速地找到表中的数据&#xff0c;而不必扫描整个数据库。…

php 生成不重复的随机字符串

md5(uniqid(md5(microtime(true)),true)) 转载于:https://www.cnblogs.com/xiaoyucoding/p/9626954.html