0
点赞
收藏
分享

微信扫一扫

杭电1003题最大子序列和


杭电1003题最大子序列和

状态转移方程是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;
}


举报

相关推荐

0 条评论