题目背景

四川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. python 错误问题解决

    获取天气信息 #encoding:UTF-8 import urllib.request import re def getHtml(url): page=urllib.request.urlopen ...

  2. 基于 win7下虚拟机的 GNSS-SDR安装过程

    最近在安装 GNSS-SDR软件时,遇到了很多问题,这里回顾了我的安装过程,罗列了所遇到的问题和解决办法.希望后来者不要再踩这些坑了! 首先,在官方文档中看到,GNSS-SDR目前并不支持直接在 Wi ...

  3. Spring框架进阶3

    Spring框架进阶3 测试spring_jdbc和spring对事务的管理 先配置相应的pom <?xml version="1.0" encoding="UTF ...

  4. spring-bean(注解方式-管理及依赖注入)

    Bean管理(注解方式) 1.添加注解的依赖包:Spring-aop.jar 2.配置spring的XML文件的引入(查官方源码) 3.开启注解的扫描 <context:component-sc ...

  5. rsync+lsyncd实现实时同步

    1.接收端安装rsync,修改/etc/rsyncd.conf配置文件,然后启动服务. uid = rootgid = rootuse chroot = nomax connection = 4sec ...

  6. Ado访问sqlserver 端口号非1433时 连接串的写法

    Provider=SQLOLEDB.;Persist Security Info=False;Data Source=hostName,Port //注意用 逗号分隔主机名与端口号

  7. PLC状态机编程第二篇-负载均衡

    控制任务 大家好,今天我们用状态机描述稍复杂的实例,同时用LAD和ST语言写状态机.我们的控制任务如下: 真空泵A和真空泵B, 按下启动按钮后, 泵A启动, 3秒后泵B也启动, 此时泵A仍运行, 当容 ...

  8. Python入门必知的几个点

    Python是Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言.全世界差不多有600多种编程语言,但流行的编程语言也就那么20来种.如果你听说过TIOB ...

  9. Python中的str

    str_lst = [ ('元素替换',), ('字符串切片',), ('字符串分割',), ('字符串连接',), ('元素计数',), ('寻找元素',), ('判断字符串的开头与结尾',), ( ...

  10. dialog BLE SDK 学习(3)

    dialog DA14580 SDK版本:5.0.4. 本文介绍了DA14580 SDK的学习感想和建议,分享给大家. 首先,Dialog官网上的资料挺全的,但是是英文的,如果英文不好,比如笔者,阅读 ...