[ZCMU OJ]5070: 序列归并(最大子序列和问题)

Description

Alice 和Bob 正在对两个序列a1, a2,..., an 和b1, b2,...,bm 进行操作。
Alice 首先需要将它们归并成一个长度为n + m 的序列c1,c2,...,cn+m。即将序列a 和b 合并成一个序列c,但不改变a 和b 的顺序。显然可能有许多许多种不同的归并结果。
Bob 需要在Alice 完成归并之后, 选择一对l,r, 满足1 ≤ l ≤ r ≤ n + m, 并使得score = cl + cl+1 + cl+2 + ...+ cr−1 + cr 尽可能地大。

不同的归并结果以及不同的选择l,r 的方式都会使得最后score 的值不尽相同,请问score 最多能达到多少呢?

Input

第一行包含一个正整数T(1 ≤ T ≤ 10),表示测试数据的组数。
每组测试数据第一行包含两个正整数n,m(1 ≤ n,m ≤ 100000),分别表示序列a 和序列b 的长度。
第二行包含n 个整数a1, a2,..., an(−109 ≤ ai ≤ 109)。
第三行包含m 个整数b1,b2,..., bm(−109 ≤ bi ≤ 109)。
输入数据保证a 和b 中至少有一个正数。

Output

对于每组测试数据,输出一行一个整数,即score 的最大值。

Sample Input

1 2 3 1 5 3 -1 -1

Sample Output

9

HINT

一种可能的归并结果是c = [1, 3, 5,−1,−1],选择l= 1, r = 3,则score = c1 + c2 + c3 = 9。

———————————————————————————————————————————

一开始我题目没审清楚,直接想用vector,结果弄巧成拙wa了。(wa↓)

#include<bits/stdc++.h>
using namespace std;
const int minn=-1e9-10;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		long long n,m;
		long long i=0;
		vector<long long>v[2];
		cin>>n>>m;
		int temp;
		while(n--)
		{
			cin>>temp;
			v[i].push_back(temp);
		}
		i++;
		while(m--)
		{
			cin>>temp;
			v[i].push_back(temp);
		}
		v[0].insert(v[0].end(),v[1].begin(),v[1].end());
		sort(v[0].begin(),v[0].end());
		
//		for(i=0;i<v[0].size();i++)
//		cout<<v[0][i]<<" ";
		long long sum=0,max=minn;
		for(i=v[0].size()-1;i>=0;i--)
		{
			sum+=v[0][i];
			if(sum>max)
			max=sum;
			else
			break;
		}
		cout<<max<<endl;
	}

}

看清题目以及hint中所提到的信息,猛一发现这不是最大子序列和的问题嘛。给定两个子序列长度,再给定两个子序列的数,分别求出两个序列的最大子序列和再相加即可。(注意一定要开long long不然会wa)

#include<bits/stdc++.h>
using namespace std;
long long mss(long long a[],long long n)
{
	long long i,thissum=0,maxsum=0;
	for(i=0;i<n;i++)
	{
		thissum+=a[i];
		if(thissum>maxsum)
		maxsum=thissum;
		else if(thissum<0)
		thissum=0;
	}
	return maxsum;
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		long long n,m,i;
		cin>>n>>m;
		long long a[n],b[m];
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		for(i=0;i<n;i++)
		cin>>a[i];
		for(i=0;i<m;i++)
		cin>>b[i];
		
		cout<<mss(a,n)+mss(b,m);
		if(t)
		cout<<endl;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值