将两个数列排序后,因为A,B各不相同,可以发现对于序列A中的Ai,和他匹配的Bj满足abs(i-j)<=2(证明的话想想显然?)
然后可以直接状压,f[i][j]表示匹配完第i个,Bi-1~Bi+2的状态
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
inline void down(ll &x,const ll y){if(x>y)x=y;}
const int maxn = 110000;
const int maxd = 16;
const ll inf = 1e12;
int n,m;
int a[maxn],b[maxn];
ll f[2][maxd];
inline ll Cal(const int x,const int y){return x==y?inf:abs(x-y);}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
sort(a+1,a+n+1);
sort(b+1,b+n+1);
for(int i=0;i<maxd;i++) f[0][i]=inf;
int now; f[now=0][3]=0;
for(int i=1;i<=n;i++)
{
now=!now; for(int j=0;j<maxd;j++) f[now][j]=inf;
for(int k=0;k<maxd;k++) if(f[!now][k]!=inf)
{
if(!(k&1)) down(f[now][k>>1],f[!now][k]+Cal(a[i],b[i-2]));
else
{
for(int j=-1;j<=2&&i+j<=n;j++) if(!((k>>1)&1<<j+1))
down(f[now][(k>>1)|(1<<j+1)],f[!now][k]+Cal(a[i],b[i+j]));
}
}
}
ll ans=f[now][3];
if(ans==inf) printf("-1\n");
else printf("%lld\n",ans);
return 0;
}