循环序列_最大子段和变种

第一次写博客....
一道icpc选拔赛的水题..
题目大意:给你一个整数的循环序列,也就是头尾相接的序列,要求找出最大的一段子段和(循环意义下的)
也就是常求的最大子段和问题,只不过这次数组头尾相接了而已

 

 
思路1:通常的方法就是复制这个整数数组接到原数组的后面,这样就变成了求有上下限的最大子段和问题,解题方法自己去查阅相关资料。

 

 

思路2:我们可以换另外一种方式来想,求最大字段和,可以先通过ans-最小子段来解出循环意义下的最大子段和,而这个最小子段就是除去首尾元素之外的最小连续子段(这样就达到了循环的意义),另外还是用最大子段和求出另外一种情况,这样两者相比较,最大者就是循环序列的最大子段和。
 

 

 

上我的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[100005],n;

int maxsum()//正常求最大连续子段和 
{
 int res,tmp;
 res=tmp=a[0];
 for(int j=1;j<n;j++)
 {
  if(tmp<0)
  tmp=a[j];
  else
  tmp+=a[j];
  
  res=max(res,tmp);
 }
 return res;
 
}
int minsum()
{
 if(n<=2)
 return 0;//如果数组元素个数小于2就直接返回 
 
 int res,tmp;
 res=tmp=a[1];
 //除去首尾结点 找出其中的最小子段和  否则意义就和maxsum相同了
 for(int j=2;j<n-1;j++)
 {
  if(tmp>0)
  tmp=a[j];
  else
  tmp+=a[j];
  
  res=min(res,tmp);
  }
  
  return res; 
 }

int main()
{
 int tt=0,ans;
 scanf("%d",&n);
 for(int i=0;i<n;i++)
 {
 scanf("%d",&a[i]);
 tt+=a[i];}
 
 /*int k1=maxsum();
 int k2=minsum();
 printf("**%d %d\n",k1,k2);*/
 
 ans=max(maxsum(),tt-minsum());
 printf("%d\n",ans);
 return 0;
 
 }

转载于:https://www.cnblogs.com/koris-yyf/p/9029962.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值