题目:
题目:最大连续子串和
描述:给定一个数字序列,A1、A2……An,求i,j,使得Ai+……Aj最大,输出这个最大和
样例:-2 11 -4 13 -5 -2
输出:20
方法一:枚举左右端点,for i j,需要O(n²)的时间复杂度,
再算出累加和,应该要O(n³),应该过不了几个样例
方法二:动态规划dp[i]的含义是最后一位是序列中第i的数字时,最大的子序列和,每次循环面临两个选择(那么我愿意称这道题为01背包),如果当前元素的前一位为结尾的最大子序列和是负数,那么如果把之前的序列添进来一定没有第i个元素单独一个数字大,所以动态转移方程很好理解:
dp[i] = max(dp[i-1] + a[i] , a[i]); //取两者更大的那个
然后只需遍历dp数组找到最大的那个元素即可,时间复杂度O(n)。
#include<algorithm>
#include <iostream>
#include<string.h>
using namespace std;
const int maxn = 10010;
int dp[maxn];
int a[maxn];
int main()
{
/*
题目:最大连续子串和
样例:-2 11 -4 13 -5 -2
输出:20
*/
int num; //序列长度
int max_value; //和最大值,答案
cin >> num;
for (int i = 0; i < num; i++)
{
cin >> a[i];
}
dp[0] = a[0]; //dp[0]结尾的最大序列一定是dp[0]本身
for (int i = 1; i < num; i++)
{
dp[i] = max(a[i], dp[i - 1] + a[i]); //转移方程
}
max_value = dp[0];
for (int i = 1; i < num; i++)
{
max_value = max(max_value, dp[i]); //找最大元素
}
cout << max_value;
return 0;
}