ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

cf1482 E. Skyline Photo

2022-05-30 23:00:49  阅读:148  来源: 互联网

标签:mf int Photo top stk Skyline max cf1482 单调


题意:

给定一排 n 个点,每个点有 \(h_i\) 和 \(v_i\)。把它们划分成任意数量的连续段,每个点仅属于一段,每段的价值等于段中 \(h\) 最小的点的 \(v\) 值。求最大价值和

\(h_i\) 为 1~n 的一个排列,\(-1e9\le v_i\le 1e9\)

思路:

用到单调(递增)栈的两个性质:1. 栈顶是左边小于 \(a_i\) 的最近位置;2. 对原数组的每个位置 \(j\)(不一定在单调栈里),\(j\) 右边最近的在单调栈里的位置 \(stk_t\) 就是 \([j,i]\) 中 \(a\) 最小的位置。

\(f_i\) 表示处理到 \(i\) 的最大价值。按 \(h_i\) 维护单调栈。有两种更新方式:

  1. 若 \(top\) 存在且与 \(i\) 放同一段,则 \(f[i]=f[stk_{top}]\);若栈为空,则 \(f[i]=v_i\);
  2. 设倒数第二段的最后一个位置为 \(j\),那么最后一段的价值为 \([j+1,i]\) 中最小的 \(v\),那么 \(\max\{f_j\}+v_t\),其中 \(t\) 为 \(j\) 右边最近的在单调栈中的位置

对于 2,\(stk_{top}\) 之前的信息已经在 \(f[stk]\) 中,要算的是新的一段即 \([stk_{top}+1,i-1]\) 中最大的 \(f\)。开个数组 \(mf[i]\) 记录一下处理到 \(i\) 时,弹出的所有 \(f\) 的最大值,包括 \(f_i\)

哎讲不清楚,这玩意太难描述了,摆了

ll n, h[N], v[N], f[N], mf[N]; //弹掉的东西的最大f值,包括自己
int stk[N], top;

void sol() {
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> h[i];
    for(int i = 1; i <= n; i++) cin >> v[i];
    
    memset(mf, -INF, sizeof mf); //初始化 

    for(int i = 1; i <= n; i++) {
        mf[i] = f[stk[top]];
        while(h[stk[top]] > h[i]) mf[i] = max(mf[i], mf[stk[top--]]);
        
        f[i] = max({top ? f[stk[top]] : v[i], mf[i] + v[i]});

        stk[++top] = i; mf[i] = max(mf[i], f[i]);
    }
    cout << f[n];
}

标签:mf,int,Photo,top,stk,Skyline,max,cf1482,单调
来源: https://www.cnblogs.com/wushansinger/p/16328694.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有