杭电1003题最大子序列和

杭电1003题最大子序列和

参考链接:
https://blog.csdn.net/chang_mu/article/details/26157759
https://blog.csdn.net/qq_16542775/article/details/50594613
状态转移方程是max(a[i],dp[i-1]+a[i])

方法一:显示使用状态转移方程

#include<iostream>
#include<cstring>
using namespace std;
/*
动态规划经典问题:最大子序列和
状态转移方式:dp[i]=max(a[i],dp[i-1]+a[i]) 
*/
int main()
{
	int t,n;
	cin>>t;
	int a[100005];  //存储数据的数组 
	int dp[100005]; //存储转移状态的数组 
	int start,end,first,last,maxn;  
	//start数组头,end数组尾,first存储最大子序列的头,last存储最大子序列的尾,maxn存储最大子序列和 
	for(int test=1;test<=t;test++)
	{
		cin>>n;
		maxn=-1005;
		memset(dp,0,sizeof(dp));
		start=end=first=last=0;
		for(int i=0;i<n;i++)
		    cin>>a[i];
		for(int i=0;i<n;i++)
		{
			if(dp[i-1]+a[i]>=a[i])
			{
				dp[i]=dp[i-1]+a[i];
				end=i;
			}
			else
			{
				dp[i]=a[i];
				start=i;
				end=i;
			}
			if(maxn<dp[i])
			{
				maxn=dp[i];
				first=start;
				last=end;
			}
		}
		cout<<"Case "<<test<<":"<<endl;
		cout<<maxn<<" "<<first+1<<" "<<last+1<<endl;
		if(test!=t)  cout<<endl;
	}
	return 0;
}

方法二:空间复杂度为O(1)
注意要对start、first、last进行初始化

#include<iostream>
#include<cstring>
using namespace std;
/*
动态规划经典问题:最大子序列和
状态转移方式:dp[i]=max(a[i],dp[i-1]+a[i]) 
*/
int main()
{
	int t,n,temp;
	cin>>t;
	int start,first,last,thisSum,maxn;  
	//start数组头,first存储最大子序列的头,last存储最大子序列的尾
	//thissum存储当前的和,maxn存储最大子序列和 
	for(int test=1;test<=t;test++)
	{
		cin>>n;  //数组的长度 
		cin>>maxn;  //数组的第一个数字
		thisSum=maxn;
		start=first=last=0;  //初始化起点和终点 
		if(maxn<0)  //如何下于0则直接从1位开始 
		{
			thisSum=0;
			start=1;  //起点从1开始 
		} 
		for(int i=1;i<n;i++)
		{
			cin>>temp;
			thisSum+=temp;
			if(thisSum>maxn)  //状态转移方程 
			{
				maxn=thisSum;
				first=start;
				last=i;
			}
			if(thisSum<0)  //如果下于0就没必要继续下去了 
			{
				thissum=0;  //重新开始下一位 
				start=i+1;  //起点为i+1 
			}
		}
		cout<<"Case "<<test<<":"<<endl;
		cout<<maxn<<" "<<first+1<<" "<<last+1<<endl;
		if(test!=t)  cout<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39905917/article/details/84308604