C 语言动态规划法解决最大子段和问题:代码逐行解释
使用 C 语言动态规划法解决最大子段和问题:代码逐行解释
a. 问题分析
给定一个整数序列,要求求出该序列连续的子段和的最大值和区间。具体而言,就是找出序列中一个连续的子序列,使得该子序列的和最大,并输出这个最大和及其区间。
b. 解题思路
动态规划法可以解决这个问题。定义一个数组 dp[],其中 dp[i] 表示以第 i 个元素结尾的子序列的最大和。则有如下递推关系:
dp[i] = max(dp[i-1] + a[i], a[i])
最终的结果即为 dp[] 数组中的最大值,同时记录下最大值对应的区间。
c. 代码
#include <stdio.h>
// 定义最大值和区间的结构体
typedef struct {
int maxSum; // 最大值
int start; // 起始位置
int end; // 结束位置
} Result;
Result findMaxSubArray(int a[], int n) {
Result result;
int dp[n]; // 定义dp数组,用于记录以每个元素结尾的子序列的最大和
dp[0] = a[0]; // 初始化dp数组
// 初始化结果结构体
result.maxSum = dp[0];
result.start = 0;
result.end = 0;
// 遍历数组,更新dp数组和结果结构体
for (int i = 1; i < n; i++) {
if (dp[i-1] + a[i] > a[i]) {
dp[i] = dp[i-1] + a[i];
} else {
dp[i] = a[i];
}
// 更新结果结构体
if (dp[i] > result.maxSum) {
result.maxSum = dp[i];
result.end = i;
}
}
// 找到起始位置
int sum = 0;
for (int i = result.end; i >= 0; i--) {
sum += a[i];
if (sum == result.maxSum) {
result.start = i;
break;
}
}
return result;
}
int main() {
int a[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
int n = sizeof(a) / sizeof(a[0]);
Result result = findMaxSubArray(a, n);
printf('最大和:%d\n', result.maxSum);
printf('区间:%d到%d\n', result.start, result.end);
return 0;
}
代码解释:
- 定义了一个用于存储最大值和区间的结构体
Result。 - 在
findMaxSubArray函数中,首先定义了一个dp数组,用于记录以每个元素结尾的子序列的最大和。然后对dp[0]进行初始化。 - 初始化结果结构体
result的最大值、起始位置和结束位置。 - 遍历数组,根据递推关系更新
dp数组和结果结构体。 - 找到起始位置,具体方法是从结果结构体的结束位置往前遍历数组,累加求和,当和等于最大值时,更新起始位置。
- 返回结果结构体
result。 - 在
main函数中,定义了一个整数序列a[],并计算出数组的长度n。 - 调用
findMaxSubArray函数,传入数组a和长度n,得到最大和和区间。 - 输出最大和和区间的结果。
注意:
- 代码中的双引号已替换为单引号。
- 代码已添加注释,并对代码进行了格式化,使其更易于阅读。
- 代码中使用了
printf函数进行输出,并添加了换行符\n。 - 代码实现了动态规划算法,并对算法进行了详细的解释。
- 代码使用了结构体来存储最大值和区间,方便输出结果。
原文地址: https://www.cveoy.top/t/topic/pfWb 著作权归作者所有。请勿转载和采集!