算法最大字段和
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
sum[0] = 0;
for (i = 1; i <= n; i++)
{
sum[i] = sum[i - 1] + a[i];
}
for (i = 0; i <= n - 1; i++) //枚举每个可能的子段
{
for (int j = i + 1; j <= n; j++)
{
t = sum[j] - sum[i];
}
if (sum > max)
max = sum;
}
}
return max;
}
3.2解题思路、伪代码(算法二)
int LSS_Enumerate(int a[]) //最大子段和,枚举算法,O(n^2)
{
int sum[101], i, n = a[0], max = -200000Leabharlann Baidu00, t; //sum[i]表示a[i]的前i项和
if (t > max)
max = t;
}
}
return max;
}
3.3解题思路、伪代码(算法三)
int LSS_Recursion(int a[], int l, int r) //最大子段和,分治算法,O(nlgn)
{
int m = (l + r) / 2, t = 0, L = 0, R = 0; //L为左区间能取到的最大,R为右区间能取到的最大
if (f[i] > max) //更新最大值
max = f[i];
}
return max;
}
4、实验步骤
4.1输入:-2,11,-4,13,-5,-2
4.2输出:4
5、讨论和分析
通过时间复杂度分析和实验结果可以看出每个算法有各自得优缺点,通过这次实验了解了算法的独特性和多样性。
{
int max = 0, n = a[0], sum;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
sum = 0; //sum为区间[i, j]之间的最大和
for (int k = i; k <= j; k++)
{
sum += a[k];
if (l == r) //边际条件:当区间元素只有一个的时候返回自身
return a[m];
if (r - l == 1) //边际条件:当区间元素只有两个的时候返回左、右、左右相加三者中的最大值
return Max(Max(a[l], a[r]), a[l] + a[r]);
int LMax = LSS_Recursion(a, l, m); //递归左区间
{
t += a[i];
if (t > R)
R = t;
}
return Max(Max(LMax, RMax), L + R); //返回左区间的和、右区间的和、两者连起来的和中最大的
}
3.4解题思路、伪代码(算法四)
int LSS_DP(int a[]) //求最大子段和,动态规划,O(n)
{
int f[101], n = a[0], max = -200000000; //f[i]表示第i个数能构成的最大和,max表示当前所有中的最大和
最大子段和问题
专业班级
智能科学与技术2016-1班
学号
2220162992
姓名
乔磊
1、实验环境
Visual Studio
2、实验目的和要求
问题重述:求解最大子段和问题
3、解题思路、伪代码
3.1解题思路、伪代码(算法一)
int LSS_SlowEnumerate(int a[]) //最大子段和,枚举算法,O(n^3)
f[1] = a[1];
for (int i = 2; i <= n; i++)
{
if (f[i - 1] > 0) //如果第i个数后面一个数能构成的最大子段和大于0
{
f[i] = f[i - 1] + a[i]; //大于就将第i个数加入其中
}
else
f[i] = a[i]; //否则第i个数自己组成一个最大子序列
int RMax = LSS_Recursion(a, m + 1, r); //递归右区间
for (int i = m; i >= 1; i--) //左边找一个最大的和
{
t += a[i];
if (t > L)
L = t;
}
t = 0;
for (int i = m + 1; i <= r; i++) //右边找一个最大的和
for (i = 1; i <= n; i++)
{
sum[i] = sum[i - 1] + a[i];
}
for (i = 0; i <= n - 1; i++) //枚举每个可能的子段
{
for (int j = i + 1; j <= n; j++)
{
t = sum[j] - sum[i];
}
if (sum > max)
max = sum;
}
}
return max;
}
3.2解题思路、伪代码(算法二)
int LSS_Enumerate(int a[]) //最大子段和,枚举算法,O(n^2)
{
int sum[101], i, n = a[0], max = -200000Leabharlann Baidu00, t; //sum[i]表示a[i]的前i项和
if (t > max)
max = t;
}
}
return max;
}
3.3解题思路、伪代码(算法三)
int LSS_Recursion(int a[], int l, int r) //最大子段和,分治算法,O(nlgn)
{
int m = (l + r) / 2, t = 0, L = 0, R = 0; //L为左区间能取到的最大,R为右区间能取到的最大
if (f[i] > max) //更新最大值
max = f[i];
}
return max;
}
4、实验步骤
4.1输入:-2,11,-4,13,-5,-2
4.2输出:4
5、讨论和分析
通过时间复杂度分析和实验结果可以看出每个算法有各自得优缺点,通过这次实验了解了算法的独特性和多样性。
{
int max = 0, n = a[0], sum;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
sum = 0; //sum为区间[i, j]之间的最大和
for (int k = i; k <= j; k++)
{
sum += a[k];
if (l == r) //边际条件:当区间元素只有一个的时候返回自身
return a[m];
if (r - l == 1) //边际条件:当区间元素只有两个的时候返回左、右、左右相加三者中的最大值
return Max(Max(a[l], a[r]), a[l] + a[r]);
int LMax = LSS_Recursion(a, l, m); //递归左区间
{
t += a[i];
if (t > R)
R = t;
}
return Max(Max(LMax, RMax), L + R); //返回左区间的和、右区间的和、两者连起来的和中最大的
}
3.4解题思路、伪代码(算法四)
int LSS_DP(int a[]) //求最大子段和,动态规划,O(n)
{
int f[101], n = a[0], max = -200000000; //f[i]表示第i个数能构成的最大和,max表示当前所有中的最大和
最大子段和问题
专业班级
智能科学与技术2016-1班
学号
2220162992
姓名
乔磊
1、实验环境
Visual Studio
2、实验目的和要求
问题重述:求解最大子段和问题
3、解题思路、伪代码
3.1解题思路、伪代码(算法一)
int LSS_SlowEnumerate(int a[]) //最大子段和,枚举算法,O(n^3)
f[1] = a[1];
for (int i = 2; i <= n; i++)
{
if (f[i - 1] > 0) //如果第i个数后面一个数能构成的最大子段和大于0
{
f[i] = f[i - 1] + a[i]; //大于就将第i个数加入其中
}
else
f[i] = a[i]; //否则第i个数自己组成一个最大子序列
int RMax = LSS_Recursion(a, m + 1, r); //递归右区间
for (int i = m; i >= 1; i--) //左边找一个最大的和
{
t += a[i];
if (t > L)
L = t;
}
t = 0;
for (int i = m + 1; i <= r; i++) //右边找一个最大的和