zoukankan      html  css  js  c++  java
  • [洛谷1868]饥饿的奶牛

    思路:

    动态规划。
    类似于线段覆盖,首先对每个区间的右端点从小到大排好序。
    对于每个区间$s_i$,状态转移方程为$f_{s_i.r}=maxlimits_{0leq jleq s_i.l}{f_j}$。
    对于这个$max$,我们可以用一个树状数组来维护前缀最大值。
    有$n$组区间,区间范围是$0sim m$,渐近时间复杂度为$O(nlog m)$。
    另外注意区间有可能为$0$,用树状数组不好维护,因此我们可以将所有的端点$+1$。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<cstring>
     4 #include<algorithm>
     5 inline int getint() {
     6     char ch;
     7     while(!isdigit(ch=getchar()));
     8     int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int N=150000,M=3000002;
    13 int m=0;
    14 class FenwickTree {
    15     private:
    16         int val[M];
    17         int lowbit(const int x) {
    18             return x&-x;
    19         }
    20     public:
    21         FenwickTree() {
    22             memset(val,0,sizeof val);
    23         }
    24         void modify(int p,const int x) {
    25             while(p<=m) {
    26                 val[p]=std::max(val[p],x);
    27                 p+=lowbit(p);
    28             }
    29         }
    30         int query(int p) {
    31             int ret=0;
    32             while(p) {
    33                 ret=std::max(ret,val[p]);
    34                 p-=lowbit(p);
    35             }
    36             return ret;
    37         }
    38 };
    39 FenwickTree t;
    40 int f[M]={0};
    41 struct Segment {
    42     int x,y;
    43     bool operator < (const Segment &another) const {
    44         return y<another.y;
    45     }
    46 };
    47 Segment s[N];
    48 int main() {
    49     int n=getint();
    50     for(register int i=0;i<n;i++) {
    51         s[i].x=getint()+1;
    52         s[i].y=getint()+1;
    53         m=std::max(m,s[i].y);
    54     }
    55     std::sort(&s[0],&s[n]);
    56     int ans=0;
    57     for(register int i=0;i<n;i++) {
    58         int &x=s[i].x,&y=s[i].y;
    59         int tmp=t.query(x-1)+y-x+1;
    60         if(tmp>f[y]) {
    61             t.modify(y,f[y]=tmp);
    62             ans=std::max(ans,tmp);
    63         }
    64     }
    65     printf("%d
    ",ans);
    66     return 0;
    67 }
  • 相关阅读:
    E
    CSU 1757 火车进站 1757
    [Unity游戏开发]场景切换
    相机跟随
    [Unity游戏开发]Vector3类
    [Unity游戏开发] 关于向量计算的一些基础
    [Unity游戏开发] MonoBehaviour类常用方法(脚本生命周期)
    C#学习笔记之——new在哪些地方用
    C#——快速排序
    C#学习笔记之——事件(Event)
  • 原文地址:https://www.cnblogs.com/skylee03/p/7381693.html
Copyright © 2011-2022 走看看