zoukankan      html  css  js  c++  java
  • 【CF442C】Artem and Array

    题目

    题目链接:https://codeforces.com/problemset/problem/442/C
    给定长度为 (n) 的数组 (a) ,你需要进行 (n) 次操作:删去某一元素 (a_i) ,并获得 (min{a_{i-1}, a_{i+1}}) 的分数。若不存在 (a_{i-1})(a_{i+1}),则此次操作不得分。

    请你计算至多能得到多少分。

    思路:

    首先任意时刻如果存在连续三个数 (x,y,z) 满足 (yleq x)(yleq z),那么此时删去 (y) 一定最优。因为如果此时不删去 (y),后面某次操作删去了 (x)(z) 中的一个,那么得分将不大于 (y),显然没有删去 (y),得分为 (min(x,z)) 优秀。
    所以我们先删去所有比他两边小的元素。注意删去一个元素 (a_i) 之后还要判断 (a_{i+1}) 是否能删去 (a_{i-1}),所以可以用一个“单调”栈维护。这个单调栈维护一个类似山峰状的元素,加入一个数 (x) 后就一直弹出栈顶直到栈顶大于栈顶第二个元素或即将加入的这个数。
    对于剩余的数,我们显然无法取到最大值和次大值,并且我们最后一定只会留下两个数,所以不是最大值和次大值的数一定都会被取。直接扫一遍计算答案即可。
    时间复杂度 (O(n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=500010;
    int n,top,max1,max2,st[N];
    ll ans;
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1,x;i<=n;i++)
    	{
    		scanf("%d",&x);
    		while (top>=2 && st[top]<=st[top-1] && st[top]<=x)
    			top--,ans+=min(st[top],x);
    		st[++top]=x;
    	}
    	for (int i=1;i<=top;i++)
    	{
    		ans+=st[i];
    		if (st[i]>max1) max2=max1,max1=st[i];
    		else if (st[i]>max2) max2=st[i];
    	}
    	printf("%lld",ans-max1-max2);
    	return 0;
    }
    
  • 相关阅读:
    js设置奇偶行数样式
    c#简单的调试信息、日志信息输出
    调用接口
    sql日期转换格式
    .net 常用方法
    日常验证
    Js 返回页面 or 跳转页面
    .NET Core Kestrel部署HTTPS以及Docker部署HTTPS
    Linux openssl生成证书
    ASP.NET Core中使用AutoMapper实现自动转化
  • 原文地址:https://www.cnblogs.com/stoorz/p/13843071.html
Copyright © 2011-2022 走看看