在学习动态规划时,看到了这个求连续子序列的最大和问题,在看了些博客之后,发现一般都是按题目要求,只是输出了最大的和,于是我想着怎么把子序列也输出来。
首先讲讲单纯输出最大和的时候吧。见核心部分代码:
cur_sum += num;
if(max < cur_sum ){
max = cur_sum;
}
if (cur_sum < 0){
cur_sum = 0;
}
这是我在别的博主那里摘来的(不是复制,所以有点不一样,但是意思差不多),这段代码不考虑全部是负数的情况,因为意义不大。当cur_sum小于0时,cur_sum = 0 ,因为这就相当于 ,把前面那一段数据看成一个整体,这个整体的和为负数,而加上一个负数一定会减小数据的,所以应当舍弃前面那个整体,并将cur_sum = 0。
对于输出子序列和:
我想到的是定义一个变量lock,用这个标志来判断是否应当更新序列的起始位置。
当有了新的 MAX 值 同时 经过了一个了一次cur_sum < 0时,那么l就要更新序列的起始位置了,同时要把lock变量取反。
lock = 0;
if(max < cur_sum ){
max = cur_sum;
if(lock){
temp_l = i;
temp_e = i;
lock = 0;
}
temp_e = i;
}
if (cur_sum < 0)
{
cur_sum = 0;
lock = 1;
}
final : 完整代码
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char const *argv[])
{
srand((unsigned)time(0));
int total,max = 0,cur_sum = 0,lock = 0,num ;
int temp_l = 0,temp_e = 0;
total = rand()%60+150;
for(int i = 0;i < total;i++){
if(i%6 == 0) printf("\n\n");
num = rand()%31 - 15;
cur_sum += num;
printf("[%4d]%3d|%5d\t\t",i, num,cur_sum);
//核心部分
if(max < cur_sum ){
max = cur_sum;
if(lock){
temp_l = i;
temp_e = i;
lock = 0; //更新序列起始位置,并将lock取反
}
temp_e = i;
}
if (cur_sum < 0)
{
cur_sum = 0;
lock = 1; //lock取反
}
}
printf("\n%d %d|max = %d\n",temp_l,temp_e,max );
return 0;
}