就是最大子段和的变体。最大子段和只要一个数组,记录前i个里的最大子段和在f[i]里就行了,但是最大子段积因为有负乘负得正这一点,所以还需要把前i个里的最小子段积存起来。就可以了。直接上代码:
/*
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std;
//输入非负整数,用法int a = get_int();
int get_int() {
int res = , ch;
while (!((ch = getchar()) >= '' && ch <= '')) {
if (ch == EOF)
return -;
}
res = ch - '';
while ((ch = getchar()) >= '' && ch <= '')
res = res * + (ch - '');
return res;
}
//输入整数(包括负整数,故不能通过返回值判断是否输入到EOF,本函数当输入到EOF时,返回-1),用法int a = get_int2();
int get_int2() {
int res = , ch, flag = ;
while (!((ch = getchar()) >= '' && ch <= '')) {
if (ch == '-')
flag = ;
if (ch == EOF)
return -;
}
res = ch - '';
while ((ch = getchar()) >= '' && ch <= '')
res = res * + (ch - '');
if (flag == )
res = -res;
return res;
} const int MAXN = ;
int maxr[MAXN], minr[MAXN]; inline int mymul(int a, int b) {
int sign = ;
if (a * b == ) {
return ;
}
if (a * b < ) {
sign = -;
}
return sign * (abs(a) + abs(b));
} int main() {
int T = get_int(), tmp, N;
int a[];
for (int t = ; t <= T; t++) {
N = get_int();
maxr[] = minr[] = ;
int ans = ;
for (int i = ; i <= N; i++) {
tmp = get_int2() / ;
a[] = mymul(maxr[i - ], tmp);
a[] = mymul(minr[i - ], tmp);
a[] = tmp;
sort(a, a + );
maxr[i] = a[];
ans = maxr[i] > ans ? maxr[i] : ans;
minr[i] = a[];
}
printf("Case #%d: %d\n", t, ans);
}
return ;
}