P2629 好消息,坏消息
好消息,坏消息
题目描述
Uim 在公司里面当秘书,现在有 条消息要告知老板。每条消息有一个好坏度,这会影响老板的心情。告知完一条消息后,老板的心情等于老板之前的心情加上这条消息的好坏度。最开始老板的心情是 ,一旦老板心情到了 以下就会勃然大怒,炒了 Uim 的鱿鱼。
Uim 为了不被炒,提前知道了这些消息(已经按时间的发生顺序进行了排列)的好坏度,希望知道如何才能不让老板发怒。
Uim 必须按照事件的发生顺序逐条将消息告知给老板。不过 Uim 可以使用一种叫 “倒叙” 的手法,例如有 条消息,Uim 可以按 (事件编号)这种顺序通报。
他希望知道,有多少个 ,可以使从 号事件开始通报到 号事件然后再从 号事件通报到 号事件可以让老板不发怒。
输入格式
第一行一个整数 (),表示有 个消息。
第二行 个整数,按时间顺序给出第 条消息的好坏度 ()。
输出格式
一行一个整数,表示可行的方案个数。
样例 #1
样例输入 #1
4 -3 5 1 2
样例输出 #1
2
提示
【样例解释】
通报事件的可行顺序(用编号表示)为 或 (分别对应 和 )
通报事件的可行顺序(用好坏度表示)为 或
【数据范围】
对于 的数据,;
对于 的数据,;
对于 的数据,。
分析
显然序列和需要非负。参考上一篇题解中的理论,找到一个最大的前缀均非负的后缀区间,遍历这个区间,找到符合条件的起点计数即可(条件见下方代码)
#include<bits/stdc++.h> using namespace std; const int N=1e6+100; long long n,g[N],sum,h[N],ans,ta; void work() { scanf("%lld",&n); for(int i=1;i<=n;++i) { scanf("%lld",g+i); sum+=g[i]; h[i]=h[i-1]+g[i]; } if(sum<0) { cout<<0; return ; } long long num=0,tot=0; for(int i=1;i<=n;++i) { num+=g[i]; if(num<0) { tot+=num; ta=i; num=0; } } num=0x7fffffff; for(int i=n;i>ta;--i) { num=min(num,h[i]); if(num-h[i-1]>=0 && h[n]-h[i-1]>=-tot) ++ans; } cout<<ans; } int main() { work(); return 0; }
本文来自博客园,作者:Glowingfire,转载请注明原文链接:https://www.cnblogs.com/Glowingfire/p/18600834
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程