hdu1003 最大子序列的和

这篇博客介绍了如何利用动态规划解决HDU1003题目的问题,即寻找一串数字中的最大子序列和。文章强调了状态转移方程`dp[i]=max{dp[i-1],dp[i-1]+a[i]}`的重要性,并指出正确处理题目格式要求是避免错误的关键。博主分享了首次通过的代码,并讨论了代码的优化,提出可以用一个变量替代两个数组,实现读入数据和累加处理同步进行。" 8677699,317644,HDFS到HBase数据批量导入指南,"['大数据', 'Hadoop', 'HBase操作', '数据迁移', '批处理']
摘要由CSDN通过智能技术生成

题目大意:给出一串数字,求出子序列中的最大和。

思路:典型的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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值