【极值问题】【CF33C】 Wonderful Randomized Sum

传送门

Description

给你一个数列A,你可以选择任意一个前缀和任意一个后缀,前缀后缀可重合。给他们乘1。求最大能获得的序列和。

Input

第一行是一个数n代表数列长度

第二行n个数字,代表序列的元素

Output

一个数字代表答案

Hint

1  n  105

Solution

发现重合的部分相当于没有修改。于是不妨设前后缀没有重合。

设修改的原序列前缀和为A,后缀和为B,未修改的部分为C,序列和为S,则有A+B+C=S

题目要求最大化(A+B)+C。又因为A+B=SC

于是要最大化2CS。发现S是一个不变量,于是要最大化C。即求一个最大字段和。显然可以DP求解。于是本题可以解决了。

Code

#include<cstdio>
#define rg register
#define ci const int
#define cl const long long

typedef long long int ll;

template <typename T>
inline void qr(T &x) {
	rg char ch=getchar(),lst=' ';
	while((ch > '9') || (ch < '0')) lst=ch,ch=getchar();
	while((ch >= '0') && (ch <= '9')) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	if(lst == '-') x=-x;
}

namespace IO {
	char buf[120];
}

template <typename T>
inline void qw(T x,const char aft,const bool pt) {
	if(x < 0) {x=-x,putchar('-');}
	rg int top=0;
	do {IO::buf[++top]=x%10+'0';} while(x/=10);
	while(top) putchar(IO::buf[top--]);
	if(pt) putchar(aft);
}

template <typename T>
inline T mmax(const T a,const T b) {return a > b ? a : b;}
template <typename T>
inline T mmin(const T a,const T b) {return a < b ? a : b;}
template <typename T>
inline T mabs(const T a) {return a < 0 ? -a : a;}

template <typename T>
inline void mswap(T &_a,T &_b) {
	T _temp=_a;_a=_b;_b=_temp;
}

const int maxn = 100010;

int n,ans,sum;
int MU[maxn],frog[maxn];

int main() {
	qr(n);
	for(rg int i=1;i<=n;++i) qr(MU[i]);
	for(rg int i=1;i<=n;++i) {
		frog[i]=mmax(frog[i],frog[i-1]+MU[i]);
		ans=mmax(ans,frog[i]);
		sum+=MU[i];
	}
	qw((ans<<1)-sum,'\n',true);
	return 0;
}

Summary

遇到最大化一个值的题目,可以通过数学推导变成单变量极值问题,然后DP或者数学求解。

posted @   一扶苏一  阅读(252)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示