原题链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1231
感谢美辰学长的指导
DP做法代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int N;
int a[10050]; //存放每一个输入数
int b[10050]; //存放以i结尾的最大和
int main()
{
while( ~scanf("%d",&N) )
{
if( N == 0 ) break;
int i;
for( i = 1; i <= N; i++ )
scanf("%d",&a[i]);
b[0] = 0;
int last = 1; //临时记录以i结尾的最大子序列的开头位置
int max_last = 1; //保存以i结尾的最大子序列的开头位置
int Max = -1;
for( i = 1; i <= N; i++ )
{
//b[i]的值就两种情况。要么从前一点接到这一点。要么从自己这点重新开始
b[i] = b[i-1] + a[i] > a[i] ? b[i-1] + a[i] : a[i];
//判断是否从该点重新开始
if( b[i] == a[i] )
last = i;
//题目要求要输出的序号最小的i,j。所以只有b[i]的值比max大。才将max_last的值修改
if( b[i] > Max )
{
max_last = last;
Max = b[i];
}
}
int k,f;
f = 0;
Max = -1;
//最大子序列的头开始寻找。找到从max_last到N之间的b[i]的最大值
for( i = max_last; i <= N; i++ )
{
//判断是否整列数都为负数
if( b[i] >= 0 )
f = 1;
if( f )
{
//max的初始值为0.即使没有大于0的数。也可以输出含有负数和0的情况
if( b[i] > Max )
{
k = i;
Max = b[i];
}
}
}
if( !f )
printf("0 %d %d\n",a[1],a[N]);
else
printf("%d %d %d\n",Max,a[max_last],a[k]);
}
return 0;
}
水题做法代码如下:
水体做法思路:
每次对tmp的值做判断
tmp > 0 判断 :
是否大于 res(对应值做修改)
tmp = 0 判断
res是否等于0(判断之前有没有出现过负数)
a[i]是否等于0(判断这一项是否为0)
tmp < 0 判断
res是否等于0(是否出现过正数(是否整列都是负数))
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int N;
int a[10050];
int main()
{
int f;
while( ~scanf("%d",&N))
{
if( N == 0 ) break;
int i;
f=0;
for( i = 1; i <= N; i++ )
scanf("%d",&a[i]);
int fs,fe,res,tmp;
int ts,te;
fs = fe = ts= te = 1;
res = tmp = 0;
for( i = 1; i <= N; i++ )
{
tmp = tmp + a[i];
if ( tmp > 0 )
{
te = i;
if( tmp > res )
{
res = tmp;
fs = ts;
fe = te;
}
}
else if ( tmp == 0 )
{
//之前没有出现过正数
if( res == 0 )
{
if( a[i] == 0 )
{
f=1;
fs = ts = i;
fe = te = i;
}
else
{
fs = ts = i + 1;
fe = te = i + 1;
}
}
//之前已经找到一段最小区间
if( res != 0 )
{
if( a[i] == 0 )
{
ts = te = i;
}
else
{
ts = te = i + 1;
}
}
}
else if( tmp < 0 )
{
if( res == 0 )
{
tmp = 0;
fs = ts = i + 1;
fe = te = i + 1;
}
else
{
tmp = 0;
ts = i + 1;
te = i + 1;
}
}
}
//输出部分
// res = 0表示没有出现过正数
if( res == 0 )
{
//不存在正数。但是存在0.
if( f )
{
printf("0 0 0\n");
continue;
}
//整列都是负数
if( fe == fs && fe >= N && a[N] != 0 )
{
printf("0 %d %d\n",a[1],a[N]);
continue;
}
}
else
//正常情况输出
printf("%d %d %d\n",res,a[fs],a[fe]);
}
return 0;
}