zoukankan      html  css  js  c++  java
  • 洛谷 P2422 良好的感觉 题解

    P2422 良好的感觉

    题目描述

    kkk做了一个人体感觉分析器。每一天,人都有一个感受值Ai,Ai越大,表示人感觉越舒适。在一段时间[i, j]内,人的舒适程度定义为[i, j]中最不舒服的那一天的感受值 * [i, j]中每一天感受值的和。现在给出kkk在连续N天中的感受值,请问,在哪一段时间,kkk感觉最舒适?

    输入格式

    第一行为N,代表数据记录的天数

    第二行N个整数,代表每一天的感受值

    输出格式

    一行,表示在最舒适的一段时间中的感受值。

    输入输出样例

    输入 #1

    6
    3 1 6 4 5 2

    输出 #1

    60

    说明/提示

    样例解释:

    kkk最开心的一段时间是第3天到第5天,开心值:(6+4+5)*4=60

    对于30%的数据,1<=N<=100

    对于70%的数据,1<=N<=2000

    对于100%的数据,1<=N<=100000,1<=感受值<=1000000

    【思路】

    单调栈
    这不就是单调栈板子题吗?

    【前缀思想】

    某个区间的总和?
    很显然可以用前缀和搞定
    嗯,没有问题
    区间不定可大可小?
    单调队列明显不行,可标签就是单调队列+DP
    怀疑自己是自己太弱
    继续想单调队列
    发现貌似单调栈好像更好写

    【中心思想】

    因为这是某个大小不定的区间里面的最小值乘以区间总和
    总和先不考虑
    一个前缀和轻轻松松
    考虑区间的最小值
    一开始想枚举区间大小
    但是区间大小太多种,而且组合方式也很多
    所以很麻烦
    但是可以这样想
    最小值一共有多少种可能 ?
    就一共只由n种
    那枚举最小值n是多少岂不美哉?
    枚举出来最小值之后就需要找区间了
    因为没有负数
    所以区间越大越好就找最大区间

    【最大区间】

    最大区间的前提是什么?
    里面的值都要大于等于枚举出来的最小值
    这是没有任何问题的
    那么这个最大区间的两边边界一定是小于这个最小值的数
    所以可以用单调栈来解决!!!

    【实现】

    单调栈单调的过程
    如果手中这个元素小于栈顶的话
    那栈顶元素当最小值的时候,
    他的右边界只能到达手中这个元素位置前面的那一个元素
    不然最小值这个称号就会易主了
    如果手中这个元素大于栈顶的话
    那手中这个元素当最小值的时候,左边的边界只能到达
    栈顶元素右边的那个位置
    不然同上最小元素的称号也会易主
    这样就可以很轻松的求出最大区间
    然后用前缀和求出区间总和乘以区间最小元素
    比较最大值
    输出就好了

    【完整代码】

    #include<iostream>
    #include<cstdio>
    #include<stack>
    #define int long long
    using namespace std;
    const int Max = 100005;
    int a[Max];
    int sum[Max];
    int l[Max];
    stack<int>s;
    signed main()
    {
    	int n;
    	cin >> n;
    	for(register int i = 1;i <= n;++ i)
    		cin >> a[i],sum[i] = sum[i - 1] + a[i];
    	int M = 0;
    	for(register int i = 1;i <= n;++ i)
    	{
    		while(!s.empty() && a[i] < a[s.top()])
    		{
    			M = max(M,(sum[i - 1] - sum[l[s.top()]]) * a[s.top()]);
    			s.pop();
    		}
    		if(!s.empty())
    		l[i] = s.top();
    		else
    		l[i] = 0;
    		s.push(i);
    	}
    	cout << M << endl;
    	return 0;
    }
    
  • 相关阅读:
    数据库课程设计
    VB.NET 数组的定义 动态使用 多维数组
    Hadoop学习之配置Eclipse远程调试Hadoop
    2014阿里巴巴研发project师暑期实习生面试经验
    SD卡中FAT32文件格式高速入门(图文具体介绍)
    Java抓取网页数据(原网页+Javascript返回数据)
    WPF中的CheckBox的_ (underscore / 下划线)丢失
    初识EPC
    SharePoint 2013 中代码创建列表查阅项字段
    代码编写逻辑(先伪代码,再带方法的逻辑,最后实现具体方法)(先控制器,再模型)
  • 原文地址:https://www.cnblogs.com/acioi/p/11688089.html
Copyright © 2011-2022 走看看