@rebirth1120
2019-11-06T19:13:15.000000Z
字数 1220
阅读 625
解题报告
有 个整数 , 将 两两配对, 要求相同的两个数不能配对, 使得每一对数的差的绝对值之和最小, 输出这个最小值.
首先, 把 从小到大排序, 若果没有 "相同的两个数不能配对" 这个条件, 那么把每一对 配对一定是最优的.
对于相等的 , 可以在 3 组数以内把它消化完,
若把它与更远的数进行配对, 肯定是不优的,
所以, 我们可以枚举三组 两两配对的所有方式, 然后取最小值就行了.
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+7;
const ll inf=1e17;
int n;
ll a[N],b[N],f[N];
int main(){
// freopen("match.in","r",stdin);
cin>>n; for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i],&b[i]);
sort(a+1,a+1+n); sort(b+1,b+1+n);
if(a[1]==b[1]) f[1]=inf;
else f[1]=abs(a[1]-b[1]);
if(a[1]==b[1]||a[2]==b[2]) f[2]=abs(a[2]-b[1])+abs(a[1]-b[2]);
else f[2]=abs(a[2]-b[2])+abs(a[1]-b[1]);
for(int i=3;i<=n;i++){
ll t1=inf,t2=inf,t3=inf,t4=inf,t5=inf;;
if(a[i]!=b[i]) t1=f[i-1]+abs(a[i]-b[i]);
if(a[i]!=b[i-1]){
if(a[i-1]!=b[i]) t2=f[i-2]+abs(a[i]-b[i-1])+abs(a[i-1]-b[i]);
if(a[i-1]!=b[i-2]&&a[i-2]!=b[i]) t3=f[i-3]+abs(a[i]-b[i-1])+abs(a[i-1]-b[i-2])+abs(a[i-2]-b[i]);
}
if(a[i]!=b[i-2]){
if(a[i-1]!=b[i]&&a[i-2]!=b[i-1]) t4=f[i-3]+abs(a[i]-b[i-2])+abs(a[i-1]-b[i])+abs(a[i-2]-b[i-1]);
if(a[i-1]!=b[i-1]&&a[i-2]!=b[i]) t5=f[i-3]+abs(a[i]-b[i-2])+abs(a[i-1]-b[i-1])+abs(a[i-2]-b[i]);
}
f[i]=min(min(t1,min(t2,t3)),min(t4,t5));
}
printf("%lld\n",f[n]);
return 0;
}