• 洛谷 T150188 区间(贪心,dp)


     传送门


     解题思路

    首先可以dp做,把数据离散化后dp[i]表示到i位置的最多区间数。

    把所有区间按照右端点排序从左往右排序,求dp[i]就用右端点为i的区间更新答案。

    状态转移可以看代码。

    这种做法常数较大,我们还可以用贪心解此题。

    我们依旧按照右端点排序,从左往右枚举所有区间,如果当前区间与前面没有重叠(即此区间的左端点在前面选择的区间右端点的右面),就选上这个区间。

    感性证明:

    能选一定要选,答案+1;

    若与前面的有重叠,那么选上这个一定使>=1个区间不能选,而且这个区间的右端点靠右,对后面的区间不利,所以不选。

    AC代码

    (贪心代码太简单这里只放dp)(其实是懒)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 const int maxn=1000005;
     8 int n,d[2*maxn],len,dp[2*maxn],cnt;
     9 struct node{
    10     int l,r;
    11 }q[maxn];
    12 bool cmp(node a,node b){
    13     return a.r!=b.r?a.r<b.r:a.l<b.l;
    14 }
    15 int main(){
    16     scanf("%d",&n);
    17     for(int i=1;i<=n;i++){
    18         scanf("%d%d",&q[i].l,&q[i].r);
    19         d[i]=q[i].l;
    20         d[i+n]=q[i].r;
    21     }
    22     sort(d+1,d+2*n+1);
    23     sort(q+1,q+n+1,cmp);
    24     len=unique(d+1,d+2*n+1)-d-1;
    25     for(int i=1;i<=n;i++){
    26         q[i].l=lower_bound(d+1,d+len+1,q[i].l)-d;
    27         q[i].r=lower_bound(d+1,d+len+1,q[i].r)-d;
    28     }
    29     for(int i=1;i<=n;i++){
    30         while(cnt<q[i].r){
    31             cnt++;
    32             dp[cnt]=dp[cnt-1];
    33         }
    34         dp[cnt]=max(dp[cnt],dp[q[i].l]+1);
    35     }
    36     printf("%d",dp[q[n].r]);
    37     return 0;
    38 }
  • 相关阅读:
    storm学习笔记
    Hbase学习笔记
    Hadoop实战项目之网站数据点击流分析(转载分析)
    Hive实战之学生选课
    Hive实战之求月销售额和累计销售额
    Hive实战之每年最高温度+时间
    Hive实战之学生课程成绩
    网易-C++开发实习生-业务初面和复面(视频)-20211028
    2021粤港澳大湾区智能网络与通信系统论坛-1026~1027-线上
    jupyter notebook
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/13770460.html
Copyright © 2020-2023  润新知