#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <stack>
#include <map>
#include <queue>
#include <cmath>
using namespace std;
int arr[200005];
int main() {
int n;
while (scanf("%d", &n) != EOF) {
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
if (n == 1) {
printf("%d\n", arr[0]);
continue;
}
int maxnum = arr[0], minnum = arr[0];
int res = arr[0];
for (int i = 1; i < n; i++) {
int mx = maxnum, mn = minnum;
//为什么要保存下Maxnum和minnum的值呢?
//如果不保存这两个值,第一条语句maxnum没问题,但在第二条语句的时候用到的maxnum要求是之前的,
//而如今maxnum已经更新,所以要想找到之前的maxnum,必须要保存起来
maxnum = max(mx * arr[i], max(arr[i], mn * arr[i]));
minnum = min(mn * arr[i], min(arr[i], mx * arr[i]));
res = max(res, maxnum);
}
/* 错误的写法
for (int i = 1; i < n; i++) {
maxnum = max(maxnum * arr[i], max(arr[i], minnum * arr[i]));
minnum = min(minnum * arr[i], min(arr[i], maxnum * arr[i]));
printf("maxnum=%d minnum=%d\n", maxnum, minnum);
res = max(res, maxnum);
}
*/
printf("%d\n", res);
}
}
要动态维护两个值maxnum和minnum,代表的值在第i - 1的位置,最小的乘积和最大的乘积分别是多少,如果当前i位置是一个正数,那么就会希望maxnum尽可能的大,如果i位置是一个负数,就会希望minnum尽可能的小。
以此遍历来找到最大值

京公网安备 11010502036488号