HDU 1231 最大连续子序列

原题目链接HDU1231


分类

HDU 动态规划 最大连续子序列


题意

(dp初步)
求最大子序列和,并且要求记录该子序列的开头数字以及结束数字(其实这样一来就可以得到整个序列了)

样例输入输出

Sample Input

6
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 3 2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0

Sample Output

20 11 13
10 1 4
10 3 5
10 10 10
0 -1 -2
0 0 0

想法

这题是在最基础的最大子序列和的基础上进行了一点点小的修改,我们都知道,对于最原始的最大子序列和问题有一个函数模板,大致思想如下:

//两种方法初始值不同
//第一种
cnt = 0;
for(int i=0;i<n;i++)//n输入序列的长度
{
    if(cnt<0)cnt = 0;//cnt为记录当前序列和的变量
    else cnt+=num[i];//num数组为输入的序列
    if(cnt>maxx)maxx = cnt;//maxx用来保存最大序列和
}

//第二种
sum = -11111;
for(int i=0;i<k;i++){//k输入序列的长度
	if(sum<0){
		sum = num[i];
	}
	else sum+=num[i];
	if(sum>MAX){
		MAX = sum;
	}
}

而对于本题,有两个注意点,第一是需要记录起始位置和结束为止,第二是题目提到可能会存在全部为负数的序列,对于这种序列,则认为最大序列和为0,并且起始位置是num[0],而结束位置是num[n-1]


代码

124ms

#include<bits/stdc++.h>
const int maxn = 11111; 
using namespace std;
int num[maxn];
int main(){
	int k;
	while(~scanf("%d",&k) && k){
		int sum = -1111;
		int MAX = -1111;
		int temp,head,tail;
		bool flag = false;
		for(int i=0;i<k;i++){
			scanf("%d",&num[i]);
			if(num[i]>=0) flag = true;
		}
		for(int i=0;i<k;i++){
			if(sum<0){
				sum = num[i];
				temp = num[i];
			}
			else{
				sum+= num[i];
			}
			if(sum>MAX){
				head = temp;
				tail = num[i];
				MAX = sum;
			}
		}
		if(flag) printf("%d %d %d\n",MAX,head,tail);
		else printf("%d %d %d\n",0,num[0],num[k-1]);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_40456064/article/details/84171263