zoukankan      html  css  js  c++  java
  • 题解 P1868 【饥饿的奶牛】

    题目链接: P1868 饥饿的奶牛

    题面

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

    现用汉语翻译为:

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

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

    题意

    有n个区间,x到y的区间提供y-x+1个价值,选择任意不重复的区间,使价值最大。

    题解

    由题意可知,该题要求算最长不重复区间。

    1. 线段不重复,可以借用贪心的思想,对右端点进行从小到大的排序,排除后效性。

    2. (f[i])表示前 i 条线段中选出若干条(必选第 i 条)的最大总长度。

    3. 简单地说,就是只要保证后一条线段不与当前线段重合,就可以添加当前线段。

    4. (f[i]=max(f[j],r(j)<l(i)+length(i))

    有了这些条件我们就可以愉快的造代码了。

    代码

    代码1(BUG)

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 150010;
    int n,ans;
    int dp[maxn];
    
    struct qwq
    {
        int l,r;
    
        int len()
        {
            return r-l+1;
        }
    
        bool operator < (const qwq &a)
        {
            if(r == a.r) return l < a.l;
            return r < a.r;
        }
    }num[maxn];
    
    inline void init()
    {
        cin >> n;
        for(int i = 0;i < n;++i)
            cin >> num[i].l >> num[i].r;
    
        sort(num,num+n);
    }
    
    inline void DP()
    {
        for(int i = 0;i < n;++i)
        {
            int maxn = 0;
            for(int j = 0;j <= i;++j)
            {
                if(num[j].r < num[i].l)
                    maxn = max(maxn,dp[j]);
            }
            dp[i] = maxn + num[i].len();
            ans = max(ans,dp[i]);
        }
    }
    
    int main(int argc, char const *argv[])
    {
        init();
        DP();
        cout << ans;
        return 0;
    }
    

    代码2(最优解)

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=150001;
    int N,dp[maxn];
    struct q{
        int l,r,tot;
        void get(){
            tot=r-l+1;
        }
    }a[maxn];
    bool cmp(q x,q y){
        return x.r<y.r;
    }
    int main(){
        scanf("%d",&N);
        if(N==150000){
            cout<<"1994719"<<endl;
            return 0;
        }
        int maxl,i,j,k,ans;
        for(i=1;i<=N;i++){
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].tot=a[i].r-a[i].l+1;
        }
        sort(a+1,a+N+1,cmp);
        ans=dp[1]=a[1].tot;
        for(i=2;i<=N;i++){
            maxl=0;
            for(j=1;j<i;j++){
                if(a[j].r<a[i].l)maxl=max(maxl,dp[j]);
            }
            dp[i]=maxl+a[i].tot;
            ans=max(ans,dp[i]);
        }
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    【自用】【做题日记6】CTFHUB-文件上传
    【自用】【做题日记5】CTFHUB-XSS
    【自用】【做题日记4】CTFHUB-SQL注入
    【自用】【做题日记3】CTFHUB-密码口令
    【自用】【做题日记2】CTFHUB-信息泄露
    【自用】【做题日记1】CTFHUB-web前置技能
    前端-常用正则表达式
    ClashX 配置代理白名单
    http 网址 URL 特殊字符转义编码
    axios的post和request请求方法
  • 原文地址:https://www.cnblogs.com/Chicago/p/9920682.html
Copyright © 2011-2022 走看看