经典题算法笔记:求最大子数组和
2016-08-12 21:42
525 查看
一、题目描述
给定一个数组a[0,...,n-1],求其最大子数组(长度>=1)和(子数组下标须连续)
输入描述:第一行一个整数n(1<=n<=5000),然后依次输入n个整数(每个整数范围[-5000, 5000])。输出描述:输出一个整数表示最大子数组和
二、暴力做法
思路十分直接。 可先固定起点也可先固定长度,枚举出所有子数组的和。但时间复杂度太高,容易超时。
我的C++代码:
#include "stdafx.h"
#include
using namespace std;
int main()
{
int n;
cin >> n;
int arr[5000];
for (int i = 0; i < n; i++)
cin >> arr[i]; int max = 0;
int sum(int i, int j, int*p);
for (int i = 0; i < n; i++)
for (int j = i; j < n; j++)
if(max
cout << max << endl;
return 0;
}
int sum(int i, int j, int*p)
{
int ans = 0;
for (int k = i; k <= j; k++)
ans = ans + *(p + k);
return ans;
}
三、动态规划做法
这种做法极大降低了时间复杂度,有效避免了很多重复计算。基本思路如下:
1.把问题变成一个递推问题,把原本是一个整体的大数组看作是由短数组递推而来的长数组。短数组的所有计算结果可以为长数组所用。
2.动态规划的思维:无后效性——前一部分如何选择对后面的选择无任何影响;最优化原理——子问题最优解导致全局最优解
3.具体做法:原问题=>在数组的n位置求a[0]到a
数组的最大子数组和=>在数组的i位置求a[0]到a[i]数组的最大子数组和,记为max[i]=>记包含a[i]的最大子数组和为CurMax[i]。若CurMax[i-1]>0那么CurMax[i]=CurMax[i-1]+a[i];(下标必须连续,又要含有a[i],所以一定含有a[i-1]),否则CurMax[i]=a[i];注意到max[i]的计算只需比较两种情况的优劣:1)含有a[i],即为CurMax[i];2)不含a[i],即为max[i-1],选择二者中较大的赋给max[i]
=>一路递推下去,到a[0]时,max[0]=a[0],CurMax[0]=a[0],完成递推
我的C++代码如下:
// lab060102.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include
using namespace std;
int main()
{
int arr[5000];
int CurMax[5000], max[5000];
int n;
cin >> n;
int i;
for (i = 0; i < n; i++)
cin >> arr[i];
CurMax[0] = arr[0];
max[0] = arr[0];
for (i = 1; i < n; i++)
{
if (CurMax[i - 1] > 0) CurMax[i] = CurMax[i - 1] + arr[i]; else CurMax[i] = arr[i]; if (CurMax[i]>max[i - 1]) max[i] = CurMax[i]; else max[i] = max[i - 1];
}
cout << max[n - 1] << endl;
return 0;
}
给定一个数组a[0,...,n-1],求其最大子数组(长度>=1)和(子数组下标须连续)
输入描述:第一行一个整数n(1<=n<=5000),然后依次输入n个整数(每个整数范围[-5000, 5000])。输出描述:输出一个整数表示最大子数组和
二、暴力做法
思路十分直接。 可先固定起点也可先固定长度,枚举出所有子数组的和。但时间复杂度太高,容易超时。
我的C++代码:
#include "stdafx.h"
#include
using namespace std;
int main()
{
int n;
cin >> n;
int arr[5000];
for (int i = 0; i < n; i++)
cin >> arr[i]; int max = 0;
int sum(int i, int j, int*p);
for (int i = 0; i < n; i++)
for (int j = i; j < n; j++)
if(max
cout << max << endl;
return 0;
}
int sum(int i, int j, int*p)
{
int ans = 0;
for (int k = i; k <= j; k++)
ans = ans + *(p + k);
return ans;
}
三、动态规划做法
这种做法极大降低了时间复杂度,有效避免了很多重复计算。基本思路如下:
1.把问题变成一个递推问题,把原本是一个整体的大数组看作是由短数组递推而来的长数组。短数组的所有计算结果可以为长数组所用。
2.动态规划的思维:无后效性——前一部分如何选择对后面的选择无任何影响;最优化原理——子问题最优解导致全局最优解
3.具体做法:原问题=>在数组的n位置求a[0]到a
数组的最大子数组和=>在数组的i位置求a[0]到a[i]数组的最大子数组和,记为max[i]=>记包含a[i]的最大子数组和为CurMax[i]。若CurMax[i-1]>0那么CurMax[i]=CurMax[i-1]+a[i];(下标必须连续,又要含有a[i],所以一定含有a[i-1]),否则CurMax[i]=a[i];注意到max[i]的计算只需比较两种情况的优劣:1)含有a[i],即为CurMax[i];2)不含a[i],即为max[i-1],选择二者中较大的赋给max[i]
=>一路递推下去,到a[0]时,max[0]=a[0],CurMax[0]=a[0],完成递推
我的C++代码如下:
// lab060102.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include
using namespace std;
int main()
{
int arr[5000];
int CurMax[5000], max[5000];
int n;
cin >> n;
int i;
for (i = 0; i < n; i++)
cin >> arr[i];
CurMax[0] = arr[0];
max[0] = arr[0];
for (i = 1; i < n; i++)
{
if (CurMax[i - 1] > 0) CurMax[i] = CurMax[i - 1] + arr[i]; else CurMax[i] = arr[i]; if (CurMax[i]>max[i - 1]) max[i] = CurMax[i]; else max[i] = max[i - 1];
}
cout << max[n - 1] << endl;
return 0;
}
相关文章推荐
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 笔试面试算法经典-打印n个数组中最大的topk
- 【算法竞赛入门经典】第三章:数组和字符串 代码和笔记
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 【算法导论学习笔记】最大子数组问题
- ] 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 算法笔记_043:最大连续子数组和(Java)
- 经典算法:超大数组,取出最大N数
- 算法笔记_133:最大连续乘积子数组(Java)
- 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 经典算法——连续子数组最大和问题
- 【LeetCode-面试算法经典-Java实现】【053-Maximum Subarray(最大子数组和)】
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 经典算法——连续子数组的最大乘积
- 【LeetCode-面试算法经典-Java实现】【152-Maximum Product Subarray(子数组的最大乘积)】
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)
- 找工作知识储备---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串