紫书刷题进行中,题解系列【GitHub|CSDN】
例题7-2 UVA11059 Maximum Product(18行AC代码)
题目大意
给定由N个整数构成的序列S,找出乘积最大的连续子序列,若最大值为负数,输出0
思路分析
对于连续子序列,枚举所有可能的起点和终点,计算区间内的乘积,取最大即可。这样看起来似乎要用一个3重循环,可进行优化,在枚举所有起点i和终点j时,在i~j计算乘积的过程中,可将j看成结尾元素,每乘上一个数,就判断是否更大(类似动态规划,利用之前已经计算出的值),以此达到优化效果
由于n最大为18,Si最大为10,因此最大连乘值为10^18,需用longlong存储
AC代码(C++11)
原始(三重循环)
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, a[20], num=0;
while (scanf("%d", &n) == 1) {
for (int i=0; i < n; i ++) scanf("%d", &a[i]);
long long maxp=0, pdt=1;
for (int i=0; i < n; i ++) { // 连续子序列起点
for (int j=i; j < n; j ++) { // 终点
pdt=1;
for (int k=i; k <= j; k ++) pdt *= (long long)a[k];
if (maxp <= pdt) maxp = pdt; // 取较大值
}
}
printf("Case #%d: The maximum product is %lld.\n\n", ++num, maxp);
}
return 0;
}
优化(二重循环)
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, a[20], num=0;
while (scanf("%d", &n) == 1) {
for (int i=0; i < n; i ++) scanf("%d", &a[i]);
long long maxp=0, pdt=1;
for (int i=0; i < n; i ++) { // 连续子序列起点
pdt=1;
for (int j=i; j < n; j ++) { // 终点(在j~n过程中,每个j表示一个终点)
pdt *= (long long)a[j];
if (maxp <= pdt) maxp = pdt; // 取较大值
}
}
printf("Case #%d: The maximum product is %lld.\n\n", ++num, maxp);
}
return 0;
}
来源:CSDN
作者:是阿俊呐
链接:https://blog.csdn.net/qq_40738840/article/details/104441973