題目:計算一個序列的最大子段乘機。
分析:動態規劃(DP)。dp過程和最大子段和類似。
因為乘數有負數,所以需要保留最小值(最小的負數乘以負數就是最大值);
狀態定義:max(i)為以i結束的子段的最大乘機,min(i)為以i結束的子段的最小乘機;
轉移方程:這裡 需要列出一個表格;
其中item(i)為當前元素數值,之所以是6種而不是8種,是因為那兩種不可能成立(min > max);
表格中沒有給出等於零的情況(此時min和max為0);
說明:注意負數的進位,╮(╯▽╰)╭。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int data[101];
int max[101][555];
int min[101][555];
int zero[555];
int one[555];
void output(int ans[])
{
int end = 550;
while (end > 0 && !ans[end]) {
end --;
}
while (end >= 0) {
printf("%d",ans[end --]);
}
puts("");
}
void mul(int ans[], int a[], int b)
{
for (int i = 0; i < 550; ++ i) {
ans[i] = a[i]*b;
}
for (int i = 0; i < 550; ++ i) {
if (ans[i] > 9 || ans[i] < -9) {
ans[i+1] += ans[i]/10;
ans[i] %= 10;
}
}
}
int bigger(int a[], int b[])
{
for (int i = 550; i >= 0; -- i) {
if (a[i] != b[i]) {
return a[i] > b[i];
}
}
return 0;
}
int main()
{
memset(zero, 0, sizeof(zero));
memset(one, 0, sizeof(one));
one[0] = 1;
int count = 1;
while (~scanf("%d",&data[count])) {
while (data[count] != -999999) {
count ++;
scanf("%d",&data[count]);
}
memset(min, 0, sizeof(min));
memset(max, 0, sizeof(max));
for (int i = 1; i < count; ++ i) {
if (data[i] > 0) {
if (bigger(min[i-1], zero)) {
mul(max[i], max[i-1], data[i]);
mul(min[i], one, data[i]);
}else if (bigger(zero, max[i-1])){
mul(max[i], one, data[i]);
mul(min[i], min[i-1], data[i]);
}else if (bigger(max[i-1], zero) || bigger(zero, min[i-1])) {
mul(max[i], max[i-1], data[i]);
mul(min[i], min[i-1], data[i]);
}else {
mul(max[i], one, data[i]);
mul(min[i], one, data[i]);
}
}else if (data[i] < 0) {
if (bigger(min[i-1], zero)) {
mul(max[i], one, data[i]);
mul(min[i], max[i-1], data[i]);
}else if (bigger(zero, max[i-1])){
mul(max[i], min[i-1], data[i]);
mul(min[i], one, data[i]);
}else if (bigger(max[i-1], zero) || bigger(zero, min[i-1])) {
mul(max[i], min[i-1], data[i]);
mul(min[i], max[i-1], data[i]);
}else {
mul(max[i], one, data[i]);
mul(min[i], one, data[i]);
}
}
}
int index = 1;
for (int i = 2; i < count; ++ i) {
if (bigger(max[i], max[index])) {
index = i;
}
}
output(max[index]);
count = 1;
}
return 0;
}