题目链接:点我
题目:给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ...,
Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,
例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和
为20。
在今年的数据结构考卷中,要求编写程序得到最大和,现在增加一个要求,即还需要输出该
子序列的第一个和最后一个元素。
使用动态规划的思维去做的会简单一点,其动态转移方程:DP[i] = max(DP[i - 1] + numbers[i], numbers[i])
每次判断一下DP数组前一个数加上当前数组的数和当前数组的数哪一个大,打的赋值给DP数组记录,然后下一步和mmax这个值比较,mmax用来记录其中最大的一个数。
解释的不是很清楚,还是直接上代码吧。
// 动态规划题
// 状态转移方程 DP[i] = max(DP[i - 1] + numbers[i], numbers[i])
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int main()
{
int n;
while(cin >> n && n)
{
int arr[10005];
int DP[10005];
int flag = false;
// 如果全是负数则无需判断
for(int i = 0; i < n; i++)
{
cin >> arr[i];
if(arr[i] >= 0)
flag = true;
}
if(flag)
{
int first, last; // 记录起点坐标和终点坐标
int temp;
int mmax;
first = last = 0;
mmax = DP[0] = arr[0];
for(int i = 1; i < n; i++)
{
if(DP[i - 1] < 0)
temp = i; // 如果上一个的和是负数则表示此次将重新开始,起点下标为temp
DP[i] = max(DP[i - 1] + arr[i], arr[i]);
if(mmax < DP[i]) // 找到和最大赋值给mmax
{
mmax = DP[i];
first = temp; // 记录最大和子序列起点下标
last = i; // 记录最大和子序列终点坐标
}
}
cout << mmax << " " << arr[first] << " " << arr[last] << endl;
}
else
{
cout << "0 " << arr[0] << " " << arr[n - 1] << endl;
}
}
return 0;
}