1007 Maximum Subsequence Sum (25分)

这题我说怎么这么熟悉,做过。乙级也有。我感觉这次我写的还是非常简洁的。哈哈。可能是因为做过,所以有一个比较简洁的思路。这题的测试点蛮刁钻(或者说严格),翻看以前的博客,以前发现了几个坑点,但还有东西可以挖掘,稀里糊涂的过了。这次可以详细的记录一下。

何时更新sum?合适更新max?(sum是序列之和,max是所求的最大连续子序列之和)

当sum小于零时,果断令sum=0,抛弃已经为负的序列和,因为任何数加上一个负数只能更小,从新的序列元素开始累加sum;当sum>max时,找到了当前最大的子序列之和,用此刻的sum更新max。

何时更新m,n?(m,n分别记录当前连续子序列有最大和的序列首元素和末元素的秩)

由m,n的定义可知,当max更新时,即可更新这两个变量。同时我在代码中设置了一个m的中间变量tempM,这个中间变量的作用是,每当sum为0之后,记录首个非负元素的秩,这个第一次很难想到为什么要设置这么一个变量,这也是我根据网上找到的测试点,结合我的代码思路来设置的。我出错的测试点有2,4,6.

第四个测试点,输入3 个元素 -1 0 -1时,应输出0 0 0。测试当最大和为0时能否正确输出。

第六个测试点,输入5 个元素1 2 3 0 0时,应输出6 1 3。测试题目给定的要求,“当连续的子序列最大和”不唯一时,输出秩i,j较小的一组。本题就是测试能否正确找到对应的j,即末尾有0,应该抛弃,输出6 1 3而不是6 1 0。

第二个测试点,蛮有意思的,有可能被人忽略的测试点。测试能否正确找到对应的i。其实有两个输入的情况(我之前就是忽略了第二种):

其一,输入5个元素0 0 0 1 2 3,应输出6 0 3,就是说前面有0,应该保留。(完成这个要求,本测试点可能还不能通过,因为还有一下一种情况)

其二,输入6个元素2 3 -6 0 1 6,应输出7 0 6。我原来的代码输出了7 6 6。插一句话,我是怎么想到这一个奇妙的输入序列呢(没错,是我自己想出来的)。

我解决的方案是,当找到序列最大和max时,才更新m和n。我引入一个变量tempM。它是当sum重新为0时,找到的的一个非负元素的秩(是非负,而不仅仅是正数,因为前面的0要保留)。这是一个新的开始,认定任何新的子序列都有可能是“最大子序列”,用tempM记录这个新序列的首元素的位置,如果之后,这个子序列的和确实比max大,用tempM更新m。如果这个子序列依然没有之前的子序列大,我们也不必担心,因为之前的最大子序列的首元素的位置用m记录,我们没有改变它的值。这是我设置tempM的原因。

下面是代码啦。有人说这题用到了动态规划?不知道,没系统学过。emmm我本来打算好好学一学这种思想的,由于各种原因耽误了,不知不觉中就用了......找时间学一学。

 1 #include<iostream>
 2 using namespace std;
 3 int main(){  
 4        int K;
 5        scanf("%d",&K);
 6        int data[K];
 7        for(int i=0;i<K;i++)
 8            scanf("%d",&data[i]);
 9            
10        int sum=0;
11        int max=-1,m=0,n=0,tempM=0;
12     int label=0;
13        for(int i=0;i<K;i++)
14        {
15            sum=sum+data[i];
16            if(label==0)
17                 {  tempM=i; 
18                    label=1;
19                 }
20            if(sum>max)
21             {
22             max=sum;
23             m=tempM;//更新m
24             n=i;//更新n 
25             }
26            if(sum<0)
27               {  sum=0;
28                  label=0;
29               }     
30         } 
31         
32         if(max>=0)
33              printf("%d %d %d",max,data[m],data[n]);
34         else
35         {
36             printf("%d %d %d",0,data[0],data[K-1]);
37         }
38 return 0;
39 }

 

posted @ 2020-03-09 20:06  wsshub  阅读(753)  评论(0)    收藏  举报