zoukankan      html  css  js  c++  java
  • [SCOI2008]配对 解题报告

    [SCOI2008]配对

    题意

    (n) 个整数 (a_i,b_i) ((a_i) 各不相同, (b_i) 也各不相同),
    ((1le nle 10^5, 1le a_i,b_i le 10^6)), 将 (a_i,b_j) 两两配对, 要求相同的两个数不能配对, 使得每一对数的差的绝对值之和最小, 输出这个最小值.

    思路

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

    因为 (a,b) 中的数各不相同, 所以对于相等的 (a_i, b_i), 可以在 3 组数以内把它消化完,
    若把它与更远的数进行配对, 肯定是不优的,

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

    代码

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=1e5+7;
    const ll inf=1e17;
    int n;
    ll a[N],b[N],f[N];
    int main(){
    //	freopen("match.in","r",stdin);
    	cin>>n; for(int i=1;i<=n;i++) scanf("%lld%lld",&a[i],&b[i]);
    	sort(a+1,a+1+n); sort(b+1,b+1+n);
    	if(a[1]==b[1]) f[1]=inf;
    	else f[1]=abs(a[1]-b[1]);
    	if(a[1]==b[1]||a[2]==b[2]) f[2]=abs(a[2]-b[1])+abs(a[1]-b[2]);
    	else f[2]=abs(a[2]-b[2])+abs(a[1]-b[1]);
    	for(int i=3;i<=n;i++){
    		ll t1=inf,t2=inf,t3=inf,t4=inf,t5=inf;;
    		if(a[i]!=b[i]) t1=f[i-1]+abs(a[i]-b[i]);
    		if(a[i]!=b[i-1]){
    			if(a[i-1]!=b[i]) t2=f[i-2]+abs(a[i]-b[i-1])+abs(a[i-1]-b[i]);
    			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]);
    		}
    		if(a[i]!=b[i-2]){
    			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]);
    			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]);
    		}
    		f[i]=min(min(t1,min(t2,t3)),min(t4,t5));
    	}
    	printf("%lld
    ",f[n]);
    	return 0;
    }
    
  • 相关阅读:
    机器学习——朴素贝叶斯
    机器学习——决策树
    机器学习——线性回归
    机器学习——KNN
    机器学习——数据预处理
    爬虫——scrapy入门
    爬虫——生产者消费者
    想写篇技术性散文
    (景德镇)麻将规则服务描述
    Visual Studio 2013环境下操作vc6/vc7/vc8等低版本平台项目【编译|生成|调试】
  • 原文地址:https://www.cnblogs.com/BruceW/p/11807482.html
Copyright © 2011-2022 走看看