问题一:最大子数组和
给定一个数组 array[1, 4, -5, 9, 8, 3, -6],在这个数字中有多个子数组,子数组和最大的应该是:[9, 8, 3],输出20,再比如数组为[1, -2, 3, 10, -4, 7, 2, -5],和最大的子数组为[3, 10, -4, 7, 2],输出18。
注意子数组和子序列的区别。字数组是连续的,子序列不要求连续。
设定dp数组,dp[i]表示以array[i]结尾并包含array[i]的最大和,注意dp[i]是一定要包含array[i],有些问题是不用包含array[i]
以array[i]结尾的子数组有两种情况:
1、只有array[i]一个元素
2、以array[i]结尾且array[i]前面有元素
那么dp[i] 的计算就是依照上面的两种情况进行计算。
对于第一种情况: dp[i] = array[i]
对于第二种情况:由于dp[i-1]是一定包含array[i-1],而子数组又要求连续的。那么dp[i] = dp[i-1] + array[i]
dp[i]的结果取两种情况的最大值。
vector<int> dp(n,0);
dp[0] = array[0];
for (int i = 1; i < n; i++)
{
dp[i] = max(array[i],array[i] + dp[i-1])
}
int maxSum = *max_element(dp.begin(),dp.end());
问题二:可以删除一个元素的最大子数组和
给定一个数组,任务是完成查找最大子数组和的功能,可以在其中最多删除一个元素以获得最大和。对一个数组array {1, 2, 3, -4, 5},要移除-4得到最大和的子数组,和为11。
vector<int> fdp(n,0);
vector<int> bdp(n,0);
fdp[0] = array[0];
for(int i=1;i<n;i++)
{
dp[i] = max(array[i],array[i]+dp[i-1]);
}
bdp[n-1] = array[n-1];
for(int i=n-2;i>=0;i--)
{
bdp[i] = max(array[i],dp[i+1]+array[i]);
}
int maxSumAll = *max_element(bdp.begin(),bdp.end());
int res = maxSumAll;
for(int i=1;i<n-1;i++)
{
res = max(res,fdp[i-1]+bdp[i+1]);
}