给定由n个数组成的序列a1,a2,……,an,序列中可能有负数,要在这n个数中选取相邻的一段ai, ai+1,……,aj(1≤i≤j≤n)使其和最大,并输出最大和,并输出最大和的子段的起止位置。当所有的数均为负数时,定义最大子段和为0。其中数据个数n和n个数据都通过键盘输入,要求使用动态规划算法实现。用C语言实现
时间: 2024-03-16 21:46:23 浏览: 42
好的,下面是使用动态规划算法实现最大子段和问题的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_N 100000
int main() {
int n, a[MAX_N];
int dp[MAX_N], start[MAX_N], end[MAX_N];
int max_sum, max_start, max_end;
// 读入序列长度和数据
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
// 初始化动态规划数组和起止位置数组
dp[0] = a[0];
start[0] = end[0] = max_start = max_end = 0;
max_sum = dp[0];
// 从第二个数开始逐个计算最大子段和
for (int i = 1; i < n; i++) {
// 如果前面的子段和为负数,就从当前位置开始计算一个新的子段
if (dp[i - 1] < 0) {
dp[i] = a[i];
start[i] = end[i] = i;
} else {
// 否则,当前位置加上前面的子段和就是当前的最大子段和
dp[i] = dp[i - 1] + a[i];
end[i] = i;
}
// 更新最大子段和及其起止位置
if (dp[i] > max_sum) {
max_sum = dp[i];
max_start = start[i];
max_end = end[i];
}
}
// 输出最大子段和及其起止位置
printf("最大子段和为:%d\n", max_sum);
printf("起始位置:%d,结束位置:%d\n", max_start, max_end);
return 0;
}
```
该代码的时间复杂度为O(n),其中n为序列长度。
阅读全文