您的位置:首页 > 其它

hdu1003 最大子序列的和

2015-08-16 16:24 253 查看
题目大意:给出一串数字,求出子序列中的最大和。

思路:典型的dp问题,状态转移方程为:dp[i]=max{dp[i-1],dp[i-1]+a[i]}.设置start和end两个指标,用来记录结果子序列中的开始和结束的位置。

值得注意的是这道题目中的格式要求很多,一开始没太在意所以wrong answer 了好几次。

如下是第一次AC的代码:

# include <iostream>
# include <algorithm>
using namespace std;

int a[100005],dp[100005];

int main ()
{
int total,t;
int n,i,k,maxs,start,end;
scanf("%d",&total);
t=total;
while(t--)
{
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
dp[1]=a[1];
maxs=dp[1];
k=start=end=1;
for(i=2;i<=n;i++)
{
if((dp[i-1]+a[i])<a[i])
{
dp[i]=a[i];
k=i;
}
else
dp[i]=dp[i-1]+a[i];
if(dp[i]>maxs)
{
maxs=dp[i];
start=k;
end=i;
}
}
printf("%s%d:\n%d %d %d\n","Case ",total-t,maxs,start,end);
if(t)
printf("\n");
}
//system("pause");
return 0;
}

之后尝试了下改进,代码如下。因为从上面的循环中可以看出,其实两个数组并没有什么用,完全可以用一个变量来替代,这样就需要在读入数据的同时做处理,边度数据,边累加处理。

# include <iostream>
# include <algorithm>
using namespace std;

int main ()
{
int total,t;
int n,i,k,maxs,start,end,sum,a;
scanf("%d",&total);
t=total;
while(t--)
{
scanf("%d",&n);
scanf("%d",&a);
start=end=k=1;
maxs=sum=a;
for(i=2;i<=n;i++)
{
scanf("%d",&a);
sum=sum+a;
if(sum<a)
{
sum=a;
k=i;
}
if(maxs<sum)
{
maxs=sum;
start=k;
end=i;
}
}
printf("%s%d:\n%d %d %d\n","Case ",total-t,maxs,start,end);
if(t)
printf("\n");
}
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息