zoukankan      html  css  js  c++  java
  • CF777E Hanoi Factory

    DP单调栈优化

    看到这道题可以很自然的想到DP

    设$dp[i]$表示最后一个$ring$为$i$的最大高度

    首先将$b$为第一关键字,$a$为第二关键字,升序排序元素

    那么对于$i$来说,它下面的$ring$的所有能转移过来的$j$,要满足$j<i$,且$b[i]>a[j]$

    所以dp转移方程为$dp[i]=max{dp[j]}+h[i](j<i,b[i]>a[j])$

    但这个转移时$O(n^{2})$的

    那么需要找出满足条件的最大$dp$值

    发现对于$i<j<k$,且$b[j]>a[i]$,$b[k]>a[j]$

    $dp[i]<dp[j]<dp[k]$,那么最后的元素就一定最优,且如果有其他不满足关系,对之后没有影响

    那么可以用单调栈维护信息

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const ll MAXN=1e5+10;
    ll n,dp[MAXN];
    struct node
    {
        ll a,b,h;
    }sh[MAXN];
    bool cmp(node a,node b)
    {
        return (a.b>b.b || (a.b==b.b && a.a>b.a));//排序
    }
    int main()
    {
        scanf("%lld",&n);
        for (ll i=1;i<=n;i++)
          scanf("%lld%lld%lld",&sh[i].a,&sh[i].b,&sh[i].h);
        sort(sh+1,sh+1+n,cmp);
        stack <ll> s;
        for (ll i=1;i<=n;i++)
        {
            while (!s.empty() && sh[s.top()].a>=sh[i].b)//单调栈维护信息
              s.pop();
            if (!s.empty())
              dp[i]=dp[s.top()];//转移
            dp[i]+=sh[i].h;
            s.push(i);
        }
        ll ans=0;
        for (ll i=1;i<=n;i++)
          ans=max(ans,dp[i]);
        printf("%lld
    ",ans);
    }
  • 相关阅读:
    浏览器为何禁止跨域(同源策略)
    viewPager
    How to remove focus without setting focus to another control?
    android ANR
    解决Ubuntu系统中文乱码显示问题
    USB 3.0规范中译本 第6章 物理层
    库&框架-----CDN网络引用总结
    18_如何排错
    17_今日回顾
    16_sql注入的原理及处理
  • 原文地址:https://www.cnblogs.com/huangchenyan/p/11253218.html
Copyright © 2011-2022 走看看