题意求一个数列中的最大子列和,给定K<10^4。由于英语太渣没读懂题,看样例还以为输出最大子列的开始和结束的下标。结果是输出开始和结束处的数值。
注意以下几点即可
1.如数列是 0 1 0 ,则输出 1 0 1(要前面的0不要后面的0)
2.如数列全小于0,如 -1 -2 -3,则输出 0 -1 -3(-1,-3为要首尾的数)
3.要前不要后 如数列 1 2 -4 3,则输出 3 1 2(而不是 3 3 3)
由于没看数据,高估了pat,所以博主解题采用了O(n)的算法。
该算法也比较容易理解 ,若数列为 a1,a2…ak。则答案序列一定为ax,ax+1…ay (1<=x<=y<=k) 设sx为前s项和,则所求答案为sy-sx,想要sy-sx最大,换句话说就是sy尽量大,sx尽量小。所以可以再输入同时就遍历记录下最小的sx 如 输入的sy-sx大于之前记录的最大值,则更新最大值,所以即可在录入数据的同时求解最大值 同时在过程中记录下来最大序列的起始值就ok
贴代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int N, n, s, ans, m = 0 ,t = 0, ix=0, iy=0;
scanf("%d%d", &N, &n);
ix = iy = t = ans = s = n;
for(int i = 1; i < N; i++) {
int flag = 0;
if(s < m)
{
flag = !flag;
m = s;
}
scanf("%d", &n);
if(flag) t = n;
s += n;
if(s - m > ans)
{
iy = n;
ix = t;
ans = s - m;
}
}
if(ans < 0) printf("0 %d %d\n",ix,n);
else printf("%d %d %d\n", ans,ix,iy);
return 0;
}
对于这道题其实并不需要 O(n)算法 暴力O(n^2)也可以过(真的水…)
下面贴O(n)代码
#include<bits/stdc++.h>
using namespace std;
const int INF = 99999999;
int main()
{
int K,n[100005];
scanf("%d",&K);
for(int i=0;i<K;i++)
scanf("%d",&a[i]);
int sum = 0, mx = -INF, s, t;
for (int i=0; i<K; i++) {
sum = 0;
for (int j=i; j<K; j++) {
sum += n[j];
if (sum > mx) {
mx = sum;
s = i;t = j;
}
}
}
if(mx < 0) printf("%d %d %d", 0,n[0], n[K-1]);
printf("%d %d %d", mx,n[s], n[t]);
}