BZOJ1237 [SCOI 2008] 配对

题目大意:有n 个整数Ai和n 个整数Bi。你需要把它们配对,即每个Ai恰好对应一 个Bp[i]。要求所有配对的整数差的绝对值之和尽量小,但不允许两个相同的数配对。

分析:乍一看像是最优匹配,但仔细看的话就可以排除了。而相等不能配对条件又让人很但疼...没它的话直接排序配对就好了。

   由于A、B中元素不重复,所以如果当前A、B不能配对,则调整一下, 直观的来看,只往最近的元素调整最优。

引用某大牛的话:事实上,一个元素的对应元素最多被调整2次...这个可以自己找下规律...因为4个以上的元素的情况可以转化成2、3个元素,最优性可用调整法证明。

                                                                      ——闹不清啊....

附代码:

 

View Code
/**************************************************************

    Problem: 1237

    User: 1012haoyifan

    Language: C++

    Result: Accepted

    Time:440 ms

    Memory:2840 kb

****************************************************************/

 

#include<cstdio>

#include<cstdlib>

#include<iostream>

#include<algorithm>

using namespace std;

#define INF 0x7ffffffffffll

#define Maxn 100001

#define P(a,b) (a==b?INF:abs(a-b))

inline long long min(long long a, long long b){ return a<b?a:b;}

int a[Maxn],b[Maxn];

int n,p1,p2,flag,ans;

long long f[Maxn];

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);

    f[1]=P(a[1],b[1]);

    f[2]=min(f[1]+P(a[2],b[2]),P(a[1],b[2])+P(a[2],b[1]));

    for (int i=3;i<=n;i++)

        f[i]=min(f[i-1]+P(a[i],b[i]),

                min(f[i-2]+P(a[i],b[i-1])+P(a[i-1],b[i]),

                    min(f[i-3]+P(a[i],b[i-2])+P(a[i-1],b[i])+P(a[i-2],b[i-1]),

                        f[i-3]+P(a[i],b[i-1])+P(a[i-1],b[i-2])+P(a[i-2],b[i])

                       )

                   )

            );

    if (f[n]>INF) printf("-1/n");

    printf("%lld",f[n]);

}



你可能感兴趣的:(2008)