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