NC15553 数学考试

数学考试

https://ac.nowcoder.com/acm/problem/15553

给定一个数组arr[ ](有正有负),选择两段子数组(子数组长度等于K)

求和最大的两段子数组,打印和

  • 先求前缀和

状态表示:

<mtext>          </mtext> l e f [ i ] ~~~~~~~~lef[i]         lef[i]表示 i i i的左边的长度为K的子数组最大和(包括 i i i)

<mtext>          </mtext> r i g [ i ] ~~~~~~~~rig[i]         rig[i]表示 i i i的右边的长度为K的子数组最大和(包括 i i i)

转移方程:

<mtext>          </mtext> l e f [ i ] = m a x ( l e f [ i 1 ] , s u m [ i ] s u m [ i K ] ) ~~~~~~~~lef[i]=max(lef[i-1],sum[i]-sum[i-K])         lef[i]=max(lef[i1],sum[i]sum[iK])

<mtext>          </mtext> r i g [ i ] = m a x ( r i g [ i + 1 ] , r i g [ i + K 1 ] s u m [ i 1 ] ) ~~~~~~~~rig[i]=max(rig[i+1], rig[i+K-1]-sum[i-1])         rig[i]=max(rig[i+1],rig[i+K1]sum[i1])

<mtext>          </mtext> a n s = m a x ( a n s , l e f [ i ] + r i g [ i + 1 ] ) ~~~~~~~~ans=max(ans,lef[i]+rig[i+1])         ans=max(ans,lef[i]+rig[i+1])
初始状态
<mtext>          </mtext> l e f [ <mtext>   </mtext> ] r i g [ <mtext>   </mtext> ] , ~~~~~~~~lef[~]和rig[~]应该初始化为最小,因为有负数         lef[ ]rig[ ],
<mtext>          </mtext> m e m s e t ( l e f , 0 x 7 f , s i z e o f ( l e f ) ) ~~~~~~~~memset(lef,-0x7f,sizeof(lef))         memset(lef,0x7f,sizeof(lef))

#define debug
#ifdef debug
#include <time.h>
#include "/home/majiao/mb.h"
#endif


#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#define MAXN ((int)2e5+7)
#define ll long long 
#define int long long 
#define INF (0x7f7f7f7f)
#define QAQ (0)

using namespace std;

#ifdef debug
#define show(x...) \ do { \ cout << "\033[31;1m " << #x << " -> "; \ err(x); \ } while (0)
void err() { cout << "\033[39;0m" << endl; }
#endif

template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }

//从一个数组里选两段长度为K的子数组a1[],a2[],要求sum_a1+sum_a2最大
int n, m, Q, K, a[MAXN], sum[MAXN];
ll lef[MAXN]; //表示位置i左边长度为K的子数组(包括i)的最大和
ll rig[MAXN]; //表示位置i右边长度为K的子数组(包括i)的最大和

signed main() {
#ifdef debug
	freopen("test", "r", stdin);
	clock_t stime = clock();
#endif
	scanf("%lld ", &Q);
	while(Q--) {
		scanf("%lld %lld ", &n, &K);
		
		memset(sum, 0, sizeof(sum));
		memset(lef, -0x7f, sizeof(lef));
		memset(rig, -0x7f, sizeof(rig));
	
		for(int i=1; i<=n; i++) 
			scanf("%lld ", a+i), sum[i]=sum[i-1]+a[i];

		for(int i=K; i<=n-K; i++) 
			lef[i] = max(lef[i-1], (sum[i]-sum[i-K]));

		for(int i=n-K+1; i>=K+1; i--) 
			rig[i] = max(rig[i+1], (sum[i+K-1]-sum[i-1]));

		//forarr(lef, 1, n, "lef");
		//forarr(rig, 1, n, "rig");
		int ans = -1e18;
		for(int i=K; i<=n-K; i++) 
			ans = max(ans, lef[i]+rig[i+1]);
		printf("%lld \n", ans);
	}




#ifdef debug
	clock_t etime = clock();
	printf("rum time: %lf 秒\n",(double) (etime-stime)/CLOCKS_PER_SEC);
#endif 
	return 0;
}


全部评论

相关推荐

头像
10-22 20:13
中南大学 Java
序言大家好呀。我是希晨er,一个初入职场的程序猿小登最近上班摸鱼刷到了一篇文章:10年深漂,放弃高薪,回长沙一年有感,还有聊聊30岁大龄程序员过往的心路历程,突然就有点感慨。我如今也做出了和大明哥一样的抉择,只是更早。此外我22年的人生,好像从来没好好记录过。正好现在工作不太忙,就想把这些经历写下来,也希望能得到社区里各位前辈的指点个人背景我是03年出生的西安娃,父母都是普通打工人。刚从中南大学软件工程专业毕业半年,现在在老家的央企过着躺平摆烂的日子成长轨迹从农村到城市的童年我家并不是西安的,只是爸妈在西安上班,从小学之后就把我接到了西安。后来老家房子拆了,爷爷奶奶也搬了过来。农村的生活,我觉...
Yki_:看哭了,恋爱那一段你女朋友说你不够关心她,可你毕竟也愿意遇到矛盾写几千字来和她慢慢分析;说不愿意给她花钱,我感觉可能只是消费观不一样;如果她想留在长沙,也应该提前跟你说开。不过她也许会心疼你放弃大厂offer转向数字马力?我也因为同样的原因有过一段幸福而充满遗憾的感情,不过跟爱情相比确实前途更重要一点。至于offer的选择,换我我也会这么选。把这些旧事记录下来以后,接下来就好好向前看吧,加油兄弟
🍊晨光随笔
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务