[贪心] Codeforces #527D. Clique Problem

本文介绍了一种基于贪心策略解决最长互不相交线段选取问题的方法,通过分析条件将问题转化为求最长路径问题,并进一步简化为经典的线段选择问题。利用树状数组进行优化,实现高效求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这题虽然简单,但思路很好。
首先肯定研究一下这个条件,尝试发现一些结论。
容易想到,若i<j<kij 有边,jk 右边,则 ik 一定有边。
这样问题就转化成,求一个从左到右的最长路。其中相邻点 i<j 满足 xixjwi+wj
分析到这里已经可以做了,直接 DP ,用树状数组优化一下,可以一个 log
但是再分析一下,观察相邻点的限制,发现这个问题还等价于,给一些线段 (wixi,wi+xi),选最多的线段互不相交。
经典问题直接贪心,变得更简单了。

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=400005;
struct data{
    int x,y;
    bool operator < (const data &B)const{
        return x<B.x;
    } 
} a[maxn];
int n,x[maxn],w[maxn],ans; 
int main(){
    freopen("D.in","r",stdin);
    freopen("D.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&w[i]), a[i].y=x[i]+w[i], a[i].x=x[i]-w[i];
    sort(a+1,a+1+n);
    a[0].x=a[0].y=-2e9;
    for(int i=1,lst=0;i<=n;i++){
        if(a[lst].y<=a[i].x) ans++, lst=i; else
        if(a[i].y<a[lst].y) lst=i;
    }
    printf("%d\n",ans);
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值