题目背景

四川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. Linux赋予普通用户root权限

    本文以新建用户admin来举例,请自行替换自己需要的用户 方法一: vi编辑 /etc/sudoers 文件,找到 root    ALL=(ALL)     ALL,在下面添加一行,如下所示: ## ...

  2. EL 和 JSTL 的使用

    EL Express Language 表达式语言 就是把<% 这里可以写java语言 %> 这种jsp的写法简化变为${ }的方式 例如 action="${pageConte ...

  3. DCMTK读取DICOM文件头信息的三种方法

    Howto: Load File Meta-Header Here's an example that shows how to load the File Meta Information Head ...

  4. java的八种基本数据类型

             据说表格的方式一目了然 一. java数据类型的取值范围如下: 注意:long型后如果不加 L 则默认为int型,float型如果不加 F 则默认为double型: 注意!注意!注意 ...

  5. (转)为什么国外 MMORPG 中不采用自动寻路等功能?

    不只是自动寻路,现在网游中的教学引导系统,辅助系统的功能强大程度,友好程度都可以说到了变态的程度,开发这些功能投入的资源甚至要超过游戏内容本身.究其原因,还是竞争越来越激烈,人心越来越浮躁,游戏商家为 ...

  6. TouTiao开源项目 分析笔记6

    1.NewsChannelBean简单类笔记 1.1.Comparable接口的实现和使用 参考文章:Comparable接口的实现和使用. 因为NewsChannelBean实现了Comparabl ...

  7. laravel5.5中间件

    目录 1. 中间件知识 1. artisan 命令 2. 文件内容 3. 前置中间件和后置中间件 4. 使用中间件 2. 控制器中间件 1. 中间件知识 1. artisan 命令 php artis ...

  8. Active Directory-Integrated Zones

    更新时间: 2010年5月 应用到: Windows Server 2003, Windows Server 2003 R2, Windows Server 2003 with SP1, Window ...

  9. 用 Flask 来写个轻博客

    用 Flask 来写个轻博客 用 Flask 来写个轻博客 (1) — 创建项目 用 Flask 来写个轻博客 (2) — Hello World! 用 Flask 来写个轻博客 (3) — (M)V ...

  10. Android如何实现毛玻璃效果之Android高级模糊技术

    自从iOS系统引入了Blur效果,也就是所谓的毛玻璃.模糊化效果,磨砂效果,各大系统就开始竞相模仿,这是怎样的一个效果呢,我们先来看一下,如下面的图片: 效果我们知道了,如何在Android中实现呢, ...