如果没有相同的数不能配的情况下,就直接排序后对位配就可以了,由单调性很好证明
然后如果有相同不能配的情况,那配对的数字在排完序的数列里一定不会跨度太大,因为离得越远意味着差值越大
然后就需要定量考虑到底要跨多少
只有相同的才会产生跨度,如果相同的有连续2个 就是交叉相连,如果3个,就有两种情况 ,如果4个,显然两个X更优
以后的就用X逼近,剩下3个就连成キ的两种情况就可以了
码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
long long n,i,j,f[99999][5],a[99999],b[99999];
int main()
{
scanf("%lld",&n);
for(i=1;i<=n;i++)
{
scanf("%lld%lld",&a[i+2],&b[i+2]);
}
sort(a+3,a+3+n); sort(b+3,b+3+n);
f[0][0]=f[1][0]=1000000000000000000;
f[2][0]=0;
for(i=3;i<=n+2;i++)//0:全都配过了 1:最后一对没配 2: 最后两对没配
{
f[i][0]=min(min(f[i-3][0]+abs(a[i]-b[i-1])+abs(a[i-1]-b[i-2])+abs(a[i-2]-b[i]),f[i-3][0]+abs(a[i]-b[i-2])+abs(a[i-1]-b[i])+abs(a[i-2]-b[i-1])),f[i-2][0]+abs(a[i]-b[i-1])+abs(b[i]-a[i-1]));
if(a[i]!=b[i])
{
f[i][0]=min(f[i-1][0]+abs(a[i]-b[i]),f[i][0]);
}
}
if(f[n+2][0]==1000000000000000000)printf("-1");
else printf("%lld",f[n+2][0]);
}