原来就写过的经典贪心,本来今天想用尺蠖法再写的,后来发现好像写不出来。。。
其实也不太算贪心,就是从头扫到尾,找当前的子序列的大小关系:
初始化sum和ans都为负无穷,然后从头开始扫,伪代码如下:
sum < 0:
if: sum < a[i]
t_start = t_end = i
sum = a[i]
if: sum > ans
ans = sum;
start = t_start
end = t_end
sum >= 0:
sum += a[i]
t_end = i
if : sum > ans
ans = sum
start = t_start
end = t_end
就这样,还有一点需要特别注意,数组要开大,我开小了re了好几次
平时用十六进制浪写小了一位
噢。。。对,这题也容易pe,注意回车啊
#include <iostream>
#include <cstdio>
#define maxn 0x3FFFF
using namespace std;
int a[maxn],n,T,t;
int main()
{
#ifdef H_R
freopen("in.txt","r",stdin);
#endif // H_R
ios::sync_with_stdio(false);
cin.tie(false);
while(cin>>T)
{
for(int f = 1 ; f <= T ; f++)
{
printf("Case %d:\n",f);
cin>>n;
a[0] = 0;
for(int i = 1 ; i <= n ; i++)
cin>>a[i];
int s,e,ts,te,sum = -maxn,ans = -maxn;
for(int i = 1 ; i <= n ; i++)
{
if(sum < 0)
{
if(sum < a[i])
{
ts = te = i;
sum = a[i];
if(ans < sum)
{
ans = sum;
s = ts;
e = te;
}
}
}
else
{
sum += a[i];
te = i;
if(sum > ans)
{
ans = sum;
s = ts;
e = te;
}
}
}
printf("%d %d %d\n",ans,s,e);
if(f != T)
putchar('\n');
}
}
return 0;
}