2014-05-10 20:31
原题:
Given an array of integers and a length L, find a sub-array of length L such that the products of all integers are the biggest.
Example:
Input: {, , -, -, },
Output: {-,-,}
题目:给定一个整数数组,其中包含正数、负数或者0。请找出乘积最大的子数组(子数组是连续的,子序列可以不连续)。不过,此处限制子数组的长度为L。
解法:因为限制了子数组的长度为L,问题解法瞬间就变了。如果没有长度限制,这应该是个比“最大子数组和”更难的动态规划。限制了长度为L以后,我们可以直接顺序计算每个长度为L的子数组的乘积。这种算法可以在线性时间内完成。不过缺点也是显而易见的:连乘一堆整数,很容易就溢出了。暂时还没想出能够不计算乘积就得出结果的办法,等我想到了再来更新这篇解题报告吧。
代码:
// http://www.careercup.com/question?id=5752271719628800
#include <climits>
#include <iostream>
#include <vector>
using namespace std; int maxSubarrayProduct(vector<int> &v, int k)
{
int n = (int)v.size(); if (n == ) {
return -;
}
if (k >= n) {
return ;
} int i, ll;
long long int product;
long long int max_product = INT_MIN; int j;
i = ;
while (i + k <= n) {
product = ;
for (j = i; j < i + k; ++j) {
if (v[j] == ) {
product = ;
break;
} else {
product *= v[j];
}
}
if (product > max_product) {
max_product = product;
ll = i;
}
if (j < i + k) {
i = j + ;
} else {
++i;
while (i + k <= n && v[i + k - ] != ) {
product = product / v[i - ] * v[i + k - ];
if (product > max_product) {
max_product = product;
ll = i;
}
++i;
}
if (i + k <= n) {
if (max_product < ) {
max_product = ;
ll = i;
}
i = i + k;
}
}
} return ll;
} int main()
{
int i;
int n;
int k;
int ll;
vector<int> v; while (cin >> n && n > ) {
v.resize(n);
for (i = ; i < n; ++i) {
cin >> v[i];
}
cin >> k;
k = k < n ? k : n;
ll = maxSubarrayProduct(v, k);
cout << '{';
for (i = ; i < k; ++i) {
i ? (cout << ' '), : ;
cout << v[i + ll];
}
cout << '}' << endl;
v.clear();
} return ;
}