[关闭]
@rebirth1120 2019-11-06T19:13:15.000000Z 字数 1220 阅读 625

[SCOI2008]配对 解题报告

解题报告


[SCOI2008]配对

题意

个整数 , 将 两两配对, 要求相同的两个数不能配对, 使得每一对数的差的绝对值之和最小, 输出这个最小值.

思路

首先, 把 从小到大排序, 若果没有 "相同的两个数不能配对" 这个条件, 那么把每一对 配对一定是最优的.

对于相等的 , 可以在 3 组数以内把它消化完,
若把它与更远的数进行配对, 肯定是不优的,

所以, 我们可以枚举三组 两两配对的所有方式, 然后取最小值就行了.

代码

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. using namespace std;
  4. const int N=1e5+7;
  5. const ll inf=1e17;
  6. int n;
  7. ll a[N],b[N],f[N];
  8. int main(){
  9. // freopen("match.in","r",stdin);
  10. cin>>n; for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i],&b[i]);
  11. sort(a+1,a+1+n); sort(b+1,b+1+n);
  12. if(a[1]==b[1]) f[1]=inf;
  13. else f[1]=abs(a[1]-b[1]);
  14. if(a[1]==b[1]||a[2]==b[2]) f[2]=abs(a[2]-b[1])+abs(a[1]-b[2]);
  15. else f[2]=abs(a[2]-b[2])+abs(a[1]-b[1]);
  16. for(int i=3;i<=n;i++){
  17. ll t1=inf,t2=inf,t3=inf,t4=inf,t5=inf;;
  18. if(a[i]!=b[i]) t1=f[i-1]+abs(a[i]-b[i]);
  19. if(a[i]!=b[i-1]){
  20. if(a[i-1]!=b[i]) t2=f[i-2]+abs(a[i]-b[i-1])+abs(a[i-1]-b[i]);
  21. if(a[i-1]!=b[i-2]&&a[i-2]!=b[i]) t3=f[i-3]+abs(a[i]-b[i-1])+abs(a[i-1]-b[i-2])+abs(a[i-2]-b[i]);
  22. }
  23. if(a[i]!=b[i-2]){
  24. if(a[i-1]!=b[i]&&a[i-2]!=b[i-1]) t4=f[i-3]+abs(a[i]-b[i-2])+abs(a[i-1]-b[i])+abs(a[i-2]-b[i-1]);
  25. if(a[i-1]!=b[i-1]&&a[i-2]!=b[i]) t5=f[i-3]+abs(a[i]-b[i-2])+abs(a[i-1]-b[i-1])+abs(a[i-2]-b[i]);
  26. }
  27. f[i]=min(min(t1,min(t2,t3)),min(t4,t5));
  28. }
  29. printf("%lld\n",f[n]);
  30. return 0;
  31. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注