BZOJ 1237: [SCOI2008]配对

25 篇文章 0 订阅

智障地度过了一个清明节 辣鸡效率。。
来写个blog。。

谢谢某位dalao的指点 问他问题的时候惨遭断句 我:问你个 智障 问题
dalao:对象是“你个智障”?
我:不不不 我要问您个问题 那是个智障问题 含义是“我是智障”

这道题很多人说不难发现 在排序之后 只会配对相邻前后的2个位置 这是为什么呢
就让本蒟蒻来证一下
首先 可以画个图
你可以自己标一下值什么的 如果有交叉 那么我们交换一下他们 那么交换后的价值是肯定<=之前的代价 可以理解为优于之前的

那么如果有配对到前后3个位置的 (随便画一个)这里写图片描述
肯定有3条交叉的线 那肯定是可以交换的 所以就不会有3个的情况 就变成至少两个了

那为什么会有两个的情况 因为题目有相等的限制啊这里写图片描述
如果f=c,a=d那就两种调整不能实现 不能变成1个的情况

嗯。。讲完了

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100010,inf=1e9+7;
inline int read()
{
    char ch=getchar(); int x=0,f=1;
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0'; ch=getchar();}
    return x*f;
}
int a[N],b[N]; LL f[N];
LL c(LL x,LL y){return x==y?inf:abs(x-y);}
int main()
{
    int n=read(),i;
    for(i=1;i<=n;i++)a[i]=read(),b[i]=read();
    if(n==1 && a[1]==b[1]){printf("-1\n"); return 0;}
    sort(a+1,a+1+n),sort(b+1,b+1+n);
    f[1]=c(a[1],b[1]),f[2]=min(f[1]+c(a[2],b[2]),c(a[1],b[2])+c(a[2],b[1]));
    for(i=3;i<=n;i++)
    {
        f[i]=f[i-1]+c(a[i],b[i]);
        f[i]=min(f[i],f[i-2]+c(a[i],b[i-1])+c(a[i-1],b[i]));
        LL u=min(c(a[i-2],b[i])+c(a[i-1],b[i-1])+c(a[i],b[i-2]),
                c(a[i-2],b[i-1])+c(a[i-1],b[i])+c(a[i],b[i-2]));
        u=min(u,c(a[i-2],b[i])+c(a[i-1],b[i-2])+c(a[i],b[i-1]));
        f[i]=min(f[i],f[i-3]+u);
    }
    printf("%lld\n",f[n]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值