【UVa1617】Laptop 笔记本(贪心)

本文介绍了一种解决线段排列问题的方法,通过贪心算法确保n条长度为1的线段排列时产生的空隙最少,并详细解释了实现步骤。

题目描述:

原题链接
题目大意:
n(n105) 条长度为 1 的线段,第 i 条线段在 [li,ri] 之间 (0liri106) 。确定他们的位置,使得他们的空隙数最少,输入保证有解。输出最少的空隙数。

算法:

贪心

做法:

设当前最后放的位置设为 r
先按左端点和右端点排序。
这时如果计算第一个区间,一定是放在最右端最优。
如果当前这个区间的右端点与 r 相等,那么一定可以通过调节上次放的位置,然后把这次的放在 r 处,使得不产生间隔(题目保证有解)
如果这个区间的右端点 > r,但左端点 <= r,那么我们可以放在 r+1 处,使得不产生间隙(如果这次的放置会使下次产生间隙,那么就产生吧,早晚都会产生的)
如果这个区间的左端点>r,那么无论如何都会产生间隙,就 cnt++,让 r 等于当前区间的右端点
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=100010;
int T, n;

struct Laptop{
    int l, r;
    bool operator < (const Laptop & rhs)const {
        return r!=rhs.r ? r<rhs.r : l<rhs.l;
    }
}a[N];

int r, cnt;

int main(){
    scanf("%d", &T);
    while(T--){
        scanf("%d", &n);
        for(int i=1; i<=n; ++i) scanf("%d%d", &a[i].l, &a[i].r);
        sort(a+1, a+n+1);
        r = a[1].r; cnt = 0;
        for(int i=1; i<=n; ++i){
            if(a[i].r==r) continue;
            if(a[i].l>r){
                cnt++;
                r = a[i].r;
            }else r++;
        }
        printf("%d\n", cnt);
    }
    while(1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值