• 洛谷P1868 饥饿的奶牛


    题目描述

    有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字。

    现用汉语翻译为:

    有N个区间,每个区间x,y表示提供的x~y共y-x+1堆优质牧草。你可以选择任意区间但不能有重复的部分。

    对于奶牛来说,自然是吃的越多越好,然而奶牛智商有限,现在请你帮助他。

    输入输出格式

    输入格式:

    第一行,N,如题

    接下来N行,每行一个数x,y,如题

    输出格式:

    一个数,最多的区间数

    输入输出样例

    输入样例#1:
    3
    1 3
    7 8
    3 4
    输出样例#1:
    5

    说明

    1<=n<=150000

    0<=x<=y<=3000000

    分析:线段覆盖的题一般来说都可以用dp做,而且方式就那么几个.一种是长度特别大,线段非常少的,而且线段数量有限制,例如:传送门,这个时候只能用线段作为状态.这道题线段和长度都非常大,只能有一维,如果设线段的话,我不知道是否和前一个线段重叠,不好处理,那么只能设坐标为状态。那么设f[i]表示1~i中能覆盖到的最多的点的个数,先把线段按照右端点排序,如果当前枚举到的这个点正好位于线段内,那么这个线段不能覆盖,那么f[i] = max{f[j]}(j < i),否则f[i] = max{f[当前线段的左端点l - 1] + r - l + 1}.当然,你也可以选择不覆盖,那么答案就是我们之前处理好的最大值.这道题和noip2010引水入城有异曲同工之妙.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    
    using namespace std;
    
    int n,f[3000010],maxx;
    
    struct node
    {
        int x,y;
    }a[150010];
    
    bool cmp(node a,node b)
    {
        return a.y < b.y;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i = 1; i <= n; i++)
        scanf("%d%d",&a[i].x,&a[i].y);
        sort(a + 1, a + 1 + n,cmp);
        for (int i = 1; i <= n; i++)
        {
            for (int j = a[i].y - 1; j >= 0; j--)
            {
                if (!f[j])
                f[j] = maxx;
                else
                break;
            }
            f[a[i].y] = max(maxx,f[a[i].x - 1] + a[i].y - a[i].x + 1);
            maxx = max(maxx,f[a[i].y]);
        }
        printf("%d
    ",f[a[n].y]);
        
        return 0;
    }
  • 相关阅读:
    JSTL标签详解
    jQuery核心基础
    JavaWeb文件上传与下载
    AOP编程模式
    2022.3.1
    2022.2.7
    Postman安装完之后打开空白
    vue项目中vueparticles的使用
    字符串中出现次数最多的字符及其出现的次数
    elementui select选择器滑动加载下一页
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7485495.html
Copyright © 2020-2023  润新知