最大子段和

题目

105.最大子段和 (15分) 
C时间限制:1 毫秒 |  C内存限制:3000 Kb
题目内容:
给定长度为n的整数序列,a[1...n], 求[1,n]某个子区间[i , j]使得
a[i]+…+a[j]和最大.或者求出最大的这个和.例如(-
2,11,-4,13,-5,2)的最大子段和为20,所求子区间为[2,4].
输入描述
第一行为一个整数n,表示数组有n个数据,第二行依次输入n个整数
 输出描述
计算出n个整数中连续k个数的最大和
 输入样例
5
1 2 3 4 5
7
6 -5 5 8 -13 5 7
输出样例
15
14

解题思路

动态规划思路 
b[j]表示以b[j]结尾的序列的最大子段和 
记b[j]=max(a[i]+a[i+1]+..+a[j]),
其中1<=i<=j,并且1<=j<=n。则所求的最大子段和为max b[j],1<=j<=n。
由b[j]的定义可易知,当b[j-1]>0时b[j]=b[j-1]+a[j],否则b[j]=a[j]。
故b[j]的动态规划递归式为:
b[j]=max(b[j-1]+a[j],a[j]),1<=j<=n。

#include<stdlib.h>
#include<stdio.h>
int main(){
 int count;
 int a[100];
 int b[100];
 int i;
 int max;
while(scanf("%d",&count)!=EOF){
 for(i=0; i<count; i++){
 	scanf("%d",&a[i]);
 }
 b[0]=a[0];
 max=b[0];
 for(i=1;i<count;i++){
	 if(b[i-1]>0)
	 	b[i]=b[i-1]+a[i];
	 else 
	 	b[i]=a[i];
	 if(b[i]>max)
	 	max=b[i];
	} 
 printf("%d\n",max);
}
 return 0;
}

如果需要输出对应字段序列,则添加两个下标存储元素就可以了

#include<stdlib.h>
#include<stdio.h>
struct Node{
	int start;
	int maxLen;
}; 
int main(){
 int count;
 int a[100];
 int b[100];
 int i;
 int max;
 int startIndex;
 int endIndex;
while(scanf("%d",&count)!=EOF){
 for(i=0; i<count; i++){
 	scanf("%d",&a[i]);
 }
 b[0]=a[0];
 max=b[0];
 startIndex=0;//b[i]所对应子段的起始元素序号 
 endIndex=0;//b[i]所对应子段的结尾元素序号
 for(i=1;i<count;i++){
	 if(b[i-1]>0){
	 	b[i]=b[i-1]+a[i];
		  
	 	if(b[i]>max){
	 		max=b[i];
	 		endIndex=i;
		}
	 	
	 }	
	 else{
	 	b[i]=a[i];
	 	
	 	if(b[i]>max){
	 		max=b[i];
	 		startIndex=i;
	 		endIndex=i;
		}	 	
	 } 
	} 
	for(int i=startIndex;i<=endIndex;i++)
 		printf("%d ",a[i]);
 	printf("\n");
}
 return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值