题目背景

四川NOI2008省选

题目描述

你有 n 个整数Ai和n 个整数Bi。你需要把它们配对,即每个Ai恰好对应一个Bp[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是不允许的,因为相同的数不许配对。

输入输出格式

输入格式:

第一行为一个正整数n,接下来是n 行,每行两个整数Ai和Bi,保证所有

Ai各不相同,Bi也各不相同。

输出格式:

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

出-1。

输入输出样例

输入样例#1:

3
3 65
45 10
60 25
输出样例#1:

32
输入样例#2:

3
5 5
6 7
8 8
输出样例#2:

5

说明

30%的数据满足:n <= 10^4

100%的数据满足:1 <= n <= 10^5,Ai和Bi均为1到10^6之间的整数。

Solution:

  这个贪心神了。。。`~`(前天写的题,本来是昨天应该写完的博客,结果因为这两天一直卡在几道题上,一直在刚题,忘记这回事了。五月断更了~)

  我们首先考虑没有限制条件,即不需要满足配对时$a_i\neq b_i$这个条件,那么很容易想到贪心的思路,直接对$a,b$从小到大排一遍序,然后累加$a,b$同项之差的绝对值即可。

  但是现在有了限制,各种方法骚,没有刚过,感觉完全不可做。

  后面仔细看题,发现一个超级重要的条件,保证$a$中数各不相同,$b$中数各不相同。

  那么就好搞了,我们先对$a,b$各自从小到大排一遍序,然后进行以下操作:

  首先考虑输出$-1$的情况:很显然只有当序列长度为$1$且$a_1=b_1$时无解,因为当$n\geq 2$时,由于数各不相同,那么同一个数$a,b$中顶多各自出现一次,我们就可以用后面的数和前面的数配对(显然一定不会相等)。

  其次,当有解时,我们贪心的想到,因为每个数顶多在$a,b$中各出现一次,所以当某次$a_i=b_i$时,则$a_i\neq b_{i-1}$且$a_i\neq b_{i+1}$($b_i$同理),于是我们可以让其和$a_{i-1},b_{i-1}$或者$a_{i+1},b_{i+1}$搭配,或者三个互相搭配,在中间取最小值就好了。(即使这三对数,每对相同,但由于$a,b$中数各自不同,那么这三对数一定可以搭配出两两不同的情况

  那么由于前两次需要判断边界,且$i+1$可能越界。于是将过程改为$a_i,a_{i-1},a_{i-2}$三个比较取最小值(都一样的)。

  排序后,求解的整个过程是线性的,于是用$DP$的思想来转移实现。

  定义状态$f[i]$表示前$i$个配对能得到的最小值,因为每次转移是三个比较,则初值$f[1]=|a_1-b_1|$,$f[2]=min(f[1]+|a2-b2|,|a1-b2|+|a2-b1|)$(注意当配对的两个数相等时,将其算出的值赋为$inf$)。

  那么不难得出状态转移方程:

  $f[i]=f[i-1]+|a_i-b_i|$(直接配对$a_i$和$b_i$)

  $f[i]=min(f[i],f[i-2]+|a_i-b_{i-1}|+|a_{i-1}-b_i|)$($i$和$i-1$配对)

  $f[i]=min(f[i],f[i-3]+|a_i-b_{i-2}|+|a_{i-1}-b_{i-1}|+|a_{i-2}-b_i|)$(三个配对时,让$i$和$i-2$配对)

  $f[i]=min(f[i],f[i-3]+|a_i-b_{i-2}|+|a_{i-1}-b_i|+|a_{i+1}-b_{i-1}|)$(三个配对时,$a,b$两两匹配的一种情况)

  $f[i]=min(f[i],f[i-3]+|a_i-b_{i-1}|+|a_{i-1}-b_{i-2}|+|a_{i+1}-b_i|)$(三个配对时,$a,b$两两匹配的另一种情况)

  最后目标状态$f[n]$就是答案。

代码:

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define Min(a,b) ((a)>(b)?(b):(a))
#define la(a,b) ((a!=b)?((a-b)>0?(a-b):(b-a)):233333333)
using namespace std;
const int N=;
ll n,f[N],a[N],b[N]; il int gi(){
int a=;char x=getchar();bool f=;
while((x<''||x>'')&&x!='-')x=getchar();
if(x=='-')x=getchar(),f=;
while(x>=''&&x<='')a=(a<<)+(a<<)+x-,x=getchar();
return f?-a:a;
} int main(){
n=gi();
For(i,,n) a[i]=gi(),b[i]=gi();
sort(a+,a+n+);sort(b+,b+n+);
if(a[]==b[]&&n==){cout<<-;return ;}
f[]=la(a[],b[]);
f[]=Min(f[]+la(a[],b[]),la(a[],b[])+la(a[],b[]));
For(i,,n){
f[i]=f[i-]+la(a[i],b[i]);
f[i]=Min(f[i],f[i-]+la(a[i],b[i-])+la(a[i-],b[i]));
f[i]=Min(f[i],f[i-]+la(a[i],b[i-])+la(a[i-],b[i])+la(a[i-],b[i-]));
f[i]=Min(f[i],f[i-]+la(a[i],b[i-])+la(a[i-],b[i-])+la(a[i-],b[i]));
f[i]=Min(f[i],f[i-]+la(a[i],b[i-])+la(a[i-],b[i])+la(a[i-],b[i-]));
}
cout<<f[n];
return ;
}

P2507 [SCOI2008]配对的更多相关文章

  1. 洛谷 P2507 [SCOI2008]配对

    P2507 [SCOI2008]配对 题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值 ...

  2. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  3. 洛谷P2507 [SCOI2008]配对 [DP,贪心]

    题目传送门 配对 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对.例如A={5,6 ...

  4. 洛谷P2507 [SCOI2008]配对

    题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对. ...

  5. luogu P2507 [SCOI2008]配对

    题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对.例如A={5,6,8},B={5, ...

  6. bzoj千题计划179:bzoj1237: [SCOI2008]配对

    http://www.lydsy.com/JudgeOnline/problem.php?id=1237 如果没有相同的数不能配对的限制 那就是排好序后 Σ abs(ai-bi) 相同的数不能配对 交 ...

  7. BZOJ1237: [SCOI2008]配对

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1237 题目大意:你有n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一 ...

  8. [SCOI2008]配对

    题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对.例如A={5,6,8},B={5, ...

  9. 1237: [SCOI2008]配对

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1789  Solved: 715[Submit][Status][Discuss] Descripti ...

随机推荐

  1. maven入门2

    1.修改maven本地仓库位置 没有效果,在新建项目时还是转跳到默认配置 在默认仓库位置添加修改后的setting文件,失败 修改成功,原因是前面修改的是setting而我们需要修改的是default ...

  2. Servlet学习笔记03——什么是DAO?

    1.案例 (1)添加用户 step1.建表 create table t_user( id int primary key auto_increment, username varchar(50) u ...

  3. 你们知道SEO每天都在做什么吗?

    医院也有做SEO的,专门负责医院网站优化工作,那么医院的SEO每天都做什么呢?偶然见到一篇文章,转载来分享给大家.感觉写的很实在. 大凡做seo工作的人都知道seo工作者每天都要做大量的外链,像有些个 ...

  4. Python学习之函数参数

    上一节,我们学习了Python中是如何定义和调用函数且如何得到返回值的.在调用函数时,有的函数需要参数来启动函数,有的则无需参数.这一节我们来介绍Python中有哪些参数类型. 位置参数 在调用函数时 ...

  5. python-1基础总结

    输入  >>> name = input() 1--如果字符串里面有很多字符都需要转义,就需要加很多\,为了简化,Python还允许用r''表示''内部的字符串默认不转义,可以自己试 ...

  6. Nginx安装,目录结构与配置文件详解

    1.Nginx简介 Nginx(发音同 engine x)是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行.由俄罗斯的程序设 ...

  7. Hive 文件格式 & Hive操作(外部表、内部表、区、桶、视图、索引、join用法、内置操作符与函数、复合类型、用户自定义函数UDF、查询优化和权限控制)

    本博文的主要内容如下: Hive文件存储格式 Hive 操作之表操作:创建外.内部表 Hive操作之表操作:表查询 Hive操作之表操作:数据加载 Hive操作之表操作:插入单表.插入多表 Hive语 ...

  8. 初见spark-04(高级算子)

    今天,这个是spark的高级算子的讲解的最后一个章节,今天我们来介绍几个简单的算子, countByKey val rdd1 = sc.parallelize(List(("a", ...

  9. P2285 [HNOI2004]打鼹鼠

    P2285 [HNOI2004]打鼹鼠 题目描述 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的.根据这个特点阿牛编写了一个打鼹鼠的游戏:在一个n*n的网格中,在某 ...

  10. getprop 与 dumpsys 命令

    Android 设备连接 PC 后,我们可以通过 adb 命令完成绝大多数工作.下面借助 getprop.dumpsys 来了解一些系统相关信息. 一.getprop 此命令的原理很简单,就是从系统的 ...