最大子数组(C语言)

1.暴力求解

#include <stdio.h>
int subset_direct(int *A,int n)
{
    int sum_max = -99999;
    for(int i=0;i<n;i++){
        int sum = 0;
        for(int j=i;j<n;j++){
            sum = sum+A[j];
            if(sum>sum_max){
                sum_max = sum;
            }
        }
    }
    return sum_max;
}
int main()
{
    int A[]={1,2,8,-3,-8,-2,6,10,5,-6};
    printf("%d\n",subset_direct(A,10));
    return 0;
}

2.分治策略

#include <stdio.h>

int max_num(int a,int b,int c)//返回3个数中的最大值
{
    int max;
    max = a;
    if(max<b)
        max = b;
    if(max<c)
        max = c;
    return max;
}

int max_subset(int A[],int left,int right)
{
    int mid,i;
    int max_left,max_right;//左半部分和右半部分最大值
    int max_left_border=0,max_right_border=0;//包括左边界和右边界的最大值
    int sum_left_border=0,sum_right_border=0;//包括左边界和右边界的值
    if(left==right){
        return A[left];
    }
    mid = (left+right)/2;
    max_left = max_subset(A,left,mid);
    max_right = max_subset(A,mid+1,right);
    for(i=mid;i>=left;i--){
        sum_left_border += A[i];
        if(sum_left_border>max_left_border){
            max_left_border = sum_left_border;
        }
    }
    for(i=mid+1;i<=right;i++){
        sum_right_border += A[i];
        if(sum_right_border>max_right_border){
            max_right_border = sum_right_border;
        }
    }
    return max_num(max_left,max_right,max_left_border+max_right_border);
}



int main()
{
    int A[] = {1,2,8,-3,-8,-2,6,10,5,-6};
    int max;
    max = max_subset(A,0,9);
    printf("%d ",max);
    return 0;
}

3.线性求解

#include <stdio.h>
int linear_subset(int A[],int n)
{
    int i;
    int temp = 0;
    int max_sum = 0;
    for(i=0;i<n;i++){
        temp +=A[i];
        if(temp>max_sum){
            max_sum = temp;
        }
        if(temp<0){
            temp = 0;
        }
    }
    return max_sum;
}
int main()
{
    int A[] = {1,2,8,-3,-8,-2,6,10,5,-6};
    int max;
    max = linear_subset(A,10);
    printf("%d ",max);
    return 0;
}

关于线性求解,我自己也说不清楚,需要自己多琢磨。
如果a[1..j]已经得到了其最大子数组,那么a[1..j+1]最大子数组只能是两种情况
(1)a[1..j+1]的最大子数组就是a[1..j];
(2)a[1..j+1]的最大子数组是a[i..j+1],1<=i<=j;
那么,如何求得所谓的(2)中的a[i..j+1]呢?
首先需要承认这样的事实,如果一个数组a[p..r]求和得到负值,那么数组a[p..r+1]的最大子数组肯定不会是a[p..r+1],因为a[p..r]+a[r+1]

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
最大数组问题是一个经典的动态规划问题,在 C 语言中可以使用动态规划算法来解决。下面是一个示例的 C 代码,用于求解最大数组的和: ```c #include <stdio.h> int maxSubArray(int* nums, int numsSize) { int maxSum = nums[0]; // 最大数组的和 int currentSum = nums[0]; // 当前数组的和 for (int i = 1; i < numsSize; i++) { // 如果当前数组的和小于0,则重新开始计算数组的和 if (currentSum < 0) { currentSum = nums[i]; } // 否则将当前元素加入数组 else { currentSum += nums[i]; } // 更新最大数组的和 if (currentSum > maxSum) { maxSum = currentSum; } } return maxSum; } int main() { int nums[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4}; int numsSize = sizeof(nums) / sizeof(nums[0]); int maxSum = maxSubArray(nums, numsSize); printf("最大数组的和为:%d\n", maxSum); return 0; } ``` 在上述代码中,`maxSubArray` 函数使用动态规划的思想,通过遍历数组来计算最大数组的和。`maxSum` 变量用于存储当前已遍历的最大数组的和,`currentSum` 变量用于存储当前数组的和。在遍历过程中,如果当前数组的和小于0,则重新开始计算数组的和;否则将当前元素加入数组。同时,通过比较当前数组的和和已遍历的最大数组的和来更新最大数组的和。最终,函数返回最大数组的和。 在 `main` 函数中,我们定义一个示例数组 `nums`,并调用 `maxSubArray` 函数来求解最大数组的和。最后,将结果打印输出。 希望以上代码能够解决你的问题!如果还有其他问题,请继续提问。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值