Maximum Energy <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Time Limit:1000MS  Memory Limit:32768K

 

Description:

Bob wanted to increase his energy by eating AC-APPLEs. There are N(1 <= N <= 150,000) AC-APPLEs, each AC-APPLE had a magic value "v" which is a positive interger and not bigger than 500. Bob visited AC-APPLEs which are given in order, every time he faced an AC-APPLE, he can choose "eat this one" or "pass this one". The odd time Bob ate, he increase v units energy. The even time Bob ate, he decrease v units energy. Before eating any AC-APPLE, Bob's enerny is 0. Please calculate the Maximum Energy Bob can increase by eating AC-APPLEs.

 

Input:

The input will consist of more than one data set. Each data set has two lines. First line has an interger N. Second line has N intergers which means the magic value of each AC-APPLEs.

 

Output:

the Maximum Energy Bob can increase

 

Sample Input:

8

7 2 1 8 4 3 5 6

 

Sample Output:

17

 

问题是这样的,以7 2 1 8 4 3 5 6为例,如果选择+7,则下一个数字则是-,比如+7,-2。你也可以选择跳过,比如+7,-1,这样就跳过2。总之加之后必定是减,加减交错。或者选择跳过。最后让你求经过这样的运算,一串数最终能得到的最大值。

 

本例中,最大值17是这么算出来的:7-1+8-3+6=17,中间跳过了245。这道题如果用穷举法来做自然可以,算法效率为O(2^N),因为每个数字上的选择只有2种:

1) /

2) 跳过

然后在所有2^N个结果中选择最大值即可。

 

但是N的最大值是150000,这种情况下,O(2^N)的效率显然无法接受。这道题可以分解成好几个子问题,于是我们可以用动态规划算法来实现算法性能的改进,使算法效率压缩到O(N)

 

我们知道,当计算到最后一个数6时,对其采取加/减或是跳过,完全取决于对7 2 1 8 4 3 5子序列的计算结果。

仔细归纳一下,不外乎4种情况:

1)如果前面的5是加的话,6自然是减

2)如果前面的5是减的话,后面的6自然是加

3)如果前面的5是跳过的话,那就直到找到从5开始往左数,第一个不跳过的数,比如是8(假如435都跳过)

a)如果8是加,则6减,类似情况1)

b)如果8是减,则6加,类似情况2)

 

而对于1)3a)来说,对6的处理是一样的,唯一不同的是计算到5和计算到8时的最大值是不一样的。所以我们只需要找到2者中的最大值进行处理,这样1)3)这两种情况可以归并为一种。同理,2),3b)也归并为一种。

 

还是以7 2 1 8 4 3 5 6为例,我们可以基于刚才的算法给出如下表:

其中add[index=1]=0,表示下一次0将加上2,或者跳过2sub[index=1]=7,表示下一次,7将减去2或者跳过2

 

当遍历到2时,我们罗列出以下4种情况:

1) 7 – 2 = 5 (后面是add)

2) 7 跳过 2 = 7 (后面继续是sub)

3) 0 + 2 = 2 (后面是sub)

4) 0 跳过2 = 0 (后面继续是add)

 

1)4)后面都是+,而1)的当前值是54)却是0,这里我们要舍弃4),选择方案1)。同理,对于2)3),后面都是-,而2)的当前值是7,大于3)的当前值2,所以舍弃方案3)。保留下来的是1)2),于是表变成了:

如果把行“+”add[]存储,把行“-”sub[]存储,7 2 1 8 …… 表示为NUM[],我们可以将其公式化为:

add[i] = max(sub[i-1]-NUM[i], add[i-1])                i)

sub[i] = max(sub[i-1], add[i-1]+NUM[i])                             ii)

 

有了公式i)ii),我们就可以将后面的表格填写完全,最终的表格为:

因为add[i] > add[i-1],且sub[i] > sub[i-1],所以最后的最大值一定是add[N]sub[N]中的一个。所以max(11,17) = 17