#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尽可能的小。
以此遍历来找到最大值