1007. Maximum Subsequence Sum(25) [动态规划,最⼤连续⼦序列和]  

1007. Maximum Subsequence Sum(25) [动态规划,最⼤连续⼦序列和]  


Given a sequence of K integers { N1, N2, …, NK }. A continuous subsequence is defined to be { Ni, Ni+1, …,
Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the
largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum
subsequence is { 11, -4, 13 } with the largest sum being 20.
Now you are supposed to find the largest sum, together with the first and the last numbers of the
maximum subsequence.


Input Specification:
Each input file contains one test case. Each case occupies two lines. The first line contains a positive
integer K (<= 10000). The second line contains K numbers, separated by a space.


Output Specification:
For each test case, output in one line the largest sum, together with the first and the last numbers of the
maximum subsequence. The numbers must be separated by one space, but there must be no extra space
at the end of a line. In case that the maximum subsequence is not unique, output the one with the
smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its
maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the
whole sequence.


Sample Input:
10
-10 1 2 3 4 -5 -23 3 7 -21


Sample Output:
10 1 4


题⽬⼤意:求最⼤连续⼦序列和,输出最⼤的和以及这个⼦序列的开始值和结束值。如果所有数都⼩
于0,那么认为最⼤的和为0,并且输出⾸尾元素

 

解:这题需要用一定动态规划的思想:

【DP的操作过程】

  一言以蔽之:大事化小,小事化了。

  将一个大问题转化成几个小问题;
  求解小问题;
  推出大问题的解。

什么是动态规划https://www.zhihu.com/question/23995189/answer/613096905

 

so这题大概就是:用一个temp表示临时最大和,当到了第i个数时,temp<0时,不管后面再来什么值,都应该将temp<0的之前内容(也就是前i个数)“舍弃”,“舍弃后”,令temp=0,同时更新left的临时值:tempindex=i+1;现在,我们的问题就从求0 ~n-1元素的最大连续子序列和缩小为了从i+1 ~ n-1元素的最大和;这样就将大问题转化成小问题了,并推出大问题的解。另外“舍弃”的前i个元素也有一个最大和,只需随时更新最大和的值就可以了。

#include <iostream>
#include <vector>
using namespace std;

int main() {
	int n;
	scanf("%d", &n);
	vector<int> v(n);
	//sum为要求的最⼤和,temp为临时最⼤和,lefindex和rightindex为所求的⼦序列的下标,tempindex标记lef的临时下标
	int leftindex = 0, rightindex = n - 1, temp = 0, tempindex = 0, sum = -1;
	for (int i = 0; i < n; i++) {
		scanf("%d", &v[i]);
		temp += v[i];
		if (temp < 0) {
			temp = 0;
			tempindex = i + 1; //前i个数之和为负,将前i个数舍掉
		}
		else if (temp>sum) {
			sum = temp;
			leftindex = tempindex;
			rightindex = i;
		}
	}

	if (sum < 0) sum = 0; //说明n个数全为负数
	printf("%d %d %d", sum, v[leftindex], v[rightindex]);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值