给定一个数组,要求数组内全部元素均为浮点数,任意取出数组里若干个连续的数相乘,请找出其乘积最大的子 数组。要求用动态规划求出最大的连续乘积子数组,同时输出所求子数组的开始位置和结束位置,请用C语言实现可运行的代码
时间: 2023-07-24 10:15:36 浏览: 80
好的,以下是我为您编写的 C 代码:
```c
#include <stdio.h>
#define N 100
int main() {
int n;
double nums[N], fmax[N], fmin[N];
int start_pos = 0, end_pos = 0;
double max_product = 1.0;
// 输入数组长度 n 和数组元素
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%lf", &nums[i]);
}
// 动态规划求解最大连续乘积子数组
fmax[0] = nums[0];
fmin[0] = nums[0];
for (int i = 1; i < n; i++) {
double tmp1 = fmax[i - 1] * nums[i];
double tmp2 = fmin[i - 1] * nums[i];
fmax[i] = fmax[i - 1] > tmp1 ? fmax[i - 1] : tmp1;
fmax[i] = fmax[i] > tmp2 ? fmax[i] : tmp2;
fmin[i] = fmin[i - 1] < tmp1 ? fmin[i - 1] : tmp1;
fmin[i] = fmin[i] < tmp2 ? fmin[i] : tmp2;
if (fmax[i] > max_product) {
max_product = fmax[i];
end_pos = i;
}
}
for (int i = 0; i <= end_pos; i++) {
if (fmax[i] == max_product) {
start_pos = i;
break;
}
}
// 输出结果
printf("最大连续乘积为 %.4lf\n", max_product);
printf("对应的子数组为:");
for (int i = start_pos; i <= end_pos; i++) {
printf("%.4lf ", nums[i]);
}
printf("\n");
printf("这个子数组的开始位置为 %d,结束位置为 %d\n", start_pos, end_pos);
return 0;
}
```
代码思路:
我们用 fmax[i] 表示以第 i 个元素结尾的最大连续乘积,fmin[i] 表示以第 i 个元素结尾的最小连续乘积。则有以下状态转移方程:
fmax[i] = max(fmax[i-1]*nums[i], fmin[i-1]*nums[i], nums[i])
fmin[i] = min(fmax[i-1]*nums[i], fmin[i-1]*nums[i], nums[i])
同时,我们记录下最大连续乘积 max_product 和对应的结束位置 end_pos。最后再遍历一遍 fmax 数组,找到最大连续乘积对应的开始位置 start_pos。
时间复杂度为 O(n),空间复杂度为 O(n)。
希望我的回答能够帮到您!
阅读全文