分治法求解最大子数组问题

/*
最大子数组问题
给出每天股票的价格,求出买进和卖出的时间,使得获利最高。
输入: P[0~n-1]
输出: 买进的时间i和卖出的时间j(0<=i<=j<=n-1)
*/
//分治法求解,将数组P转换为数组A,其中A中每个元素A[i]=P[i]-p[i-1],表示第i-1天买进,第i天卖出的获利。
//那么第i天买进第j天卖出的获利可以表示为A[i+1]+...+A[j],0<=i<j<n
//经过这样的转换后,问题就成了寻找A中最大的非空连续数组,称为最大子数组。
//利用分治法求解
//当数组A的长度为1时,A[left,right],left=right,那么i=left-1,j=right;
//当数组A的长度大于1时,将数组A一分为二:m=(left+right)/2;
//最大子数组存在的位置有三个位置:1.数组A[left,m]中;2.数组A[m+1,right]中;3.横跨数组A[left,m]和A[m+1,right],即i在left~m范围,j在m+1~right范围。
//
#include <stdio.h>
#include <stdlib.h>
struct ans {
int low, high, sum;
};
void FindMaxSub(int A[], int low, int high, struct ans *a);
void FindMaxCrosSub(int A[], int low, int mid, int high, struct ans *a);
int main()
{
int *A = NULL;
int B[17] = { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
int n = 0, i = 0;
struct ans Ans;
scanf("%d", &n);
A = (int *)malloc(sizeof(int)*n);
for(i = 0; i<n; i++){
scanf("%d",A+i);
}
for (i = n - 1; i>0; i--) {
A[i] = A[i] - A[i - 1];
}
FindMaxSub(A, 1, n - 1, &Ans);
printf("\n low = %d, high = %d, sum = %d\n", Ans.low, Ans.high, Ans.sum);
system("pause");
return 0;
}
void FindMaxSub(int A[], int low, int high, struct ans *a)
{
if (low == high) {
a->low = a->high = low;
a->sum = A[low];
}
else {
struct ans a1, a2, a3;
int mid = (low + high) / 2;
FindMaxSub(A, low, mid, &a1);
FindMaxSub(A, mid + 1, high, &a2);
FindMaxCrosSub(A, low, mid, high, &a3);
// printf("low=%d,mid=%d,high=%d\n", low, mid, high);
// printf("a1.low=%d, a1.high=%d, a1.sum=%d\n", a1.low, a1.high, a1.sum);
// printf("a2.low=%d, a2.high=%d, a2.sum=%d\n", a2.low, a2.high, a2.sum);
// printf("a3.low=%d, a3.high=%d, a3.sum=%d\n", a3.low, a3.high, a3.sum);
if (a1.sum >= a2.sum && a1.sum >= a3.sum) {
a->low = a1.low;
a->high = a1.high;
a->sum = a1.sum;
}
else if (a2.sum >= a1.sum && a2.sum >= a3.sum) {
a->low = a2.low;
a->high = a2.high;
a->sum = a2.sum;
}
else {
a->low = a3.low;
a->high = a3.high;
a->sum = a3.sum;
}
//printf("a->low=%d, a->high=%d, a->sum=%d\n", a->low, a->high, a->sum);
}
}
void FindMaxCrosSub(int A[], int low, int mid, int high, struct ans *a)
{
int leftsum = A[mid], rightsum = A[mid + 1];
int minleft, i, maxright, j;
int sum = 0;
minleft = i = mid;
maxright = j = mid + 1;
while (i >= low) {
sum += A[i];
if (sum>leftsum) {
leftsum = sum;
minleft = i;
}
i--;
}
sum = 0;
while (j <= high) {
sum += A[j];
if (sum>rightsum) {
rightsum = sum;
maxright = j;
}
j++;
}
a->low = minleft;
a->high = maxright;
a->sum = (leftsum + rightsum);
}
posted @   main_c  阅读(707)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示