P2507 [SCOI2008]配对
题目背景
四川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。
输入输出样例
3
3 65
45 10
60 25
32
3
5 5
6 7
8 8
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]配对的更多相关文章
- 洛谷 P2507 [SCOI2008]配对
P2507 [SCOI2008]配对 题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值 ...
- 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)
洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...
- 洛谷P2507 [SCOI2008]配对 [DP,贪心]
题目传送门 配对 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对.例如A={5,6 ...
- 洛谷P2507 [SCOI2008]配对
题目背景 四川NOI2008省选 题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对. ...
- luogu P2507 [SCOI2008]配对
题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对.例如A={5,6,8},B={5, ...
- bzoj千题计划179:bzoj1237: [SCOI2008]配对
http://www.lydsy.com/JudgeOnline/problem.php?id=1237 如果没有相同的数不能配对的限制 那就是排好序后 Σ abs(ai-bi) 相同的数不能配对 交 ...
- BZOJ1237: [SCOI2008]配对
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1237 题目大意:你有n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一 ...
- [SCOI2008]配对
题目描述 你有 n 个整数Ai和n 个整数Bi.你需要把它们配对,即每个Ai恰好对应一个Bp[i].要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对.例如A={5,6,8},B={5, ...
- 1237: [SCOI2008]配对
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1789 Solved: 715[Submit][Status][Discuss] Descripti ...
随机推荐
- python 错误问题解决
获取天气信息 #encoding:UTF-8 import urllib.request import re def getHtml(url): page=urllib.request.urlopen ...
- 基于 win7下虚拟机的 GNSS-SDR安装过程
最近在安装 GNSS-SDR软件时,遇到了很多问题,这里回顾了我的安装过程,罗列了所遇到的问题和解决办法.希望后来者不要再踩这些坑了! 首先,在官方文档中看到,GNSS-SDR目前并不支持直接在 Wi ...
- Spring框架进阶3
Spring框架进阶3 测试spring_jdbc和spring对事务的管理 先配置相应的pom <?xml version="1.0" encoding="UTF ...
- spring-bean(注解方式-管理及依赖注入)
Bean管理(注解方式) 1.添加注解的依赖包:Spring-aop.jar 2.配置spring的XML文件的引入(查官方源码) 3.开启注解的扫描 <context:component-sc ...
- rsync+lsyncd实现实时同步
1.接收端安装rsync,修改/etc/rsyncd.conf配置文件,然后启动服务. uid = rootgid = rootuse chroot = nomax connection = 4sec ...
- Ado访问sqlserver 端口号非1433时 连接串的写法
Provider=SQLOLEDB.;Persist Security Info=False;Data Source=hostName,Port //注意用 逗号分隔主机名与端口号
- PLC状态机编程第二篇-负载均衡
控制任务 大家好,今天我们用状态机描述稍复杂的实例,同时用LAD和ST语言写状态机.我们的控制任务如下: 真空泵A和真空泵B, 按下启动按钮后, 泵A启动, 3秒后泵B也启动, 此时泵A仍运行, 当容 ...
- Python入门必知的几个点
Python是Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言.全世界差不多有600多种编程语言,但流行的编程语言也就那么20来种.如果你听说过TIOB ...
- Python中的str
str_lst = [ ('元素替换',), ('字符串切片',), ('字符串分割',), ('字符串连接',), ('元素计数',), ('寻找元素',), ('判断字符串的开头与结尾',), ( ...
- dialog BLE SDK 学习(3)
dialog DA14580 SDK版本:5.0.4. 本文介绍了DA14580 SDK的学习感想和建议,分享给大家. 首先,Dialog官网上的资料挺全的,但是是英文的,如果英文不好,比如笔者,阅读 ...