Vijos 1617 超级教主

1|0原题链接

1|0题解

f[i] 表示跳到 i 所能取到的最大价值,则我们需要取一个 j(j<i) 使 f[j]+sum[i]sum[j]i100 最大,其中 sum 数组表示前缀和,所以转移方程即为:

f[i]=max(f[j]+sum[i]sum[j]i100)

将常数提出:

f[i]=max(f[j]sum[j])+sum[i]i100

用单调队列维护即可。

2|0Code:

#include<bits/stdc++.h> #define int long long using namespace std; void read(int &x) { char ch=getchar(); int r=0,w=1; while(!isdigit(ch))w=ch=='-'?-1:1,ch=getchar(); while(isdigit(ch))r=(r<<3)+(r<<1)+(ch^48),ch=getchar(); x=r*w; } const int N=2e6+100; int a[N],f[N],line[N],s[N]; main() { int n,m; read(n);read(m); for(int i=1;i<=n;i++) read(a[i]),s[i]=s[i-1]+a[i],f[i]=INT_MIN; f[0]=m; int head=1,tail=0; for(int i=0;i<=n;i++) { while(head<=tail&&f[line[tail]]-s[line[tail]]<f[i]-s[i])tail--; line[++tail]=i; while(head<=tail&&f[line[head]]<i*100)head++; f[i]=f[line[head]]-s[line[head]]+s[i]-i*100; } cout<<f[n]; return 0; }

__EOF__

本文作者JMartin
本文链接https://www.cnblogs.com/LAK666/p/16449954.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Epoch_L  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示