暴力枚举法:O(n^3) 级复杂度, 可以求出最大连续子序列的范围;
直接两个for循环枚举子序列的首尾,然后再来个循环计算序列的和,每次更新和的最大值。
#include <cstdio>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
int num[N], left, right;
int Sum (int a[], int st, int ed) //求连续区间 [st, ed] 之间的和
{
int sum=0;
for (int i=st; i<=ed; i++)
sum += a[i];
return sum;
}
// 枚举所有可能的区间,找到其中有最大值的区间即可
int MaxSubSum (int a[], int n)
{
int Max = -INF;
for (int i=0; i<n; i++) //起点
{
int cursum = 0;
for (int j=i; j<n; j++) // 终点
{
cursum = Sum (a, i, j);
if (cursum > Max)
{
Max = cursum;
left = i; right = j;
}
}
}
return Max;
}
int main ()
{
int t, n;
freopen ("test.txt","r",stdin);
scanf ("%d",&t);
while (t--)
{
scanf ("%d",&n);
for (int i=0; i<n; i++)
scanf ("%d",num+i);
int ans = MaxSubSum (num, n); //若把此函数放在printf函数中输出,范围会出错
printf ("%d %d %d\n", ans, left+1, right+1);
}
return 0;
}
算法和上一个什么改变,就是把求和的循环预处理了一下。从而可以在每次枚举区间的时候直接算出,而不用每次都循环得出区间的和。
#include <cstdio>
#include <cstring>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
int sum[N], num[N];
int left, right;
int MaxSubSum (int n)
{
int maxsum = -INF;
for (int i=0; i<n; i++)
{
for (int j=i; j<n; j++)
{
int cursum = sum[j] - sum[i] + num[i];
if (cursum > maxsum)
{
maxsum = cursum;
left = i, right = j;
}
}
}
return maxsum;
}
int main ()
{
int t, n;
freopen ("test.txt","r",stdin);
scanf ("%d",&t);
while (t--)
{
scanf ("%d",&n);
memset (sum, 0, sizeof sum);
int tmp = 0;
for (int i=0; i<n; i++)
{
scanf ("%d",num+i);
tmp += num[i];
sum[i] = tmp;
}
int ans = MaxSubSum (n);
printf ("%d %d %d\n", ans, left+1, right+1);
}
return 0;
}
#include <cstdio>
#include <cstring>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
int num[N];
int left, right;
int MaxSubSum (int a[], int n)
{
int maxsum = -INF;
int st=0, cursum=0;
for (int i=0; i<n; i++)
{
if (cursum + a[i] < a[i])
{
cursum = a[i];
st = i;
}
else cursum += a[i];
if (cursum > maxsum)
{
maxsum = cursum;
left = st;
right = i;
}
}
return maxsum;
}
int main ()
{
int t, n;
freopen ("test.txt","r",stdin);
scanf ("%d",&t);
while (t--)
{
scanf ("%d",&n);
for (int i=0; i<n; i++)
scanf ("%d",num+i);
int ans = MaxSubSum (num, n);
printf ("%d %d %d\n", ans, left+1, right+1);
}
return 0;
}