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



posted @ 2012-04-09 08:51  Evan1004  阅读(591)  评论(0编辑  收藏  举报