https://cn.vjudge.net/problem/HYSBZ-1237
你有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是不允许的,因 为相同的数不许配对。
Input
第一行为一个正整数n,接下来是n 行,每行两个整数Ai和Bi,保证所有 Ai各不相同,Bi也各不相同。
Output
输出一个整数,即配对整数的差的绝对值之和的最小值。如果无法配对,输 出-1。
Sample Input
3 3 65 45 10 60 25
Sample Output
32
Hint
1 <= n <= 10^5,Ai和Bi均为1到10^6之间的整数。
(数据好像并没有不能配对的那种情况)
如果没有相同的数不能配的情况下,就直接排序后对位配就可以了,由单调性很好证明
然后如果有相同不能配的情况,那配对的数字在排完序的数列里一定不会跨度太大,因为离得越远意味着差值越大
然后就需要定量考虑到底要跨多少
只有相同的才会产生跨度,如果相同的有连续2个 就是交叉相连,如果3个,就有两种情况 ,如果4个,显然两个X更优
以后的就用X逼近,剩下3个就连成キ的两种情况就可以了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<list>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const ll INF=1e15;
const int N=1e5+5;
ll a[N],b[N];
ll dp[N];
ll f(ll x,ll y){
if(x==y) return INF;
else return abs(x-y);
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&a[i],&b[i]);
}
if(n==1&&a[1]==b[1]) printf("-1\n");
sort(a+1,a+1+n);
sort(b+1,b+1+n);
dp[1]=f(a[1],b[1]);
if(n>=2) dp[2]=min(dp[1]+f(a[2],b[2]),f(a[1],b[2])+f(a[2],b[1]));
for(int i=3;i<=n;i++){
dp[i]=dp[i-1]+f(a[i],b[i]);
dp[i]=min(dp[i],dp[i-2]+f(a[i],b[i-1])+f(a[i-1],b[i]));
dp[i]=min(dp[i],dp[i-3]+f(a[i],b[i-1])+f(a[i-1],b[i-2])+f(a[i-2],b[i]));
dp[i]=min(dp[i],dp[i-3]+f(a[i],b[i-2])+f(a[i-1],b[i])+f(a[i-2],b[i-1]));
}
printf("%lld\n",dp[n]);
return 0;
}