03532: 最大上升子序列和
dp, http://cs101.openjudge.cn/practice/03532
一个数的序列bi,当b~1~ < b~2~ < ... < b~S~的时候,我们称这个序列是上升的。对于给定的一个序列(a~1~, a~2~, ...,a~N~),我们可以得到一些上升的子序列(a~i1~, a~i2~, ..., a~iK~),这里1 <= i1 < i2 < ... < iK <= N。比如,对于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。这些子序列中序列和最大为18,为子序列(1, 3, 5, 9)的和.
你的任务,就是对于给定的序列,求出最大上升子序列和。注意,最长的上升子序列的和不一定是最大的,比如序列(100, 1, 2, 3)的最大上升子序列和为100,而最长上升子序列为(1, 2, 3)
输入
输入的第一行是序列的长度N (1 <= N <= 1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000(可能重复)。
输出
最大上升子序列和
样例输入
7
1 7 3 5 9 4 8样例输出
18思路:从第一个数开始逐次递推,考虑第 i个数的情况时,再从第一个数开始逐个检验,如果第 i个数大于前 i个数中的第 j个数,那么将前 j个数的最大上升子序列和再加上第 i个数,即构成前 i个数上升子序列和的一种情况,再取这些情况中的最大值,即得到前 i个数的最大上升子序列和。最后依次递推,即可得到整个序列的最大上升子序列和。
主要思路就是记录把每个数作为序列最后一位时的序列和,取 max。即,以每一项为末项的最大上升子序列和。
2020fall-cs101,邹思清。感觉跟我之前做的dp不太一样。之前的dp大多是计算n位之前满足的答案,而这道题使用的递推公式也不仅仅是相邻几项,而且还使用了max,做的时候没有想到,又学到新方法了。
input()
b = [int(x) for x in input().split()]
n = len(b)
dp = [0]*n
for i in range(n):
dp[i] = b[i]
for j in range(i):
if b[j]<b[i]:
dp[i] = max(dp[j]+b[i], dp[i])
print(max(dp))2020fall-cs101,李东航
import copy
n = int(input())
a = list(map(int, input().split()))
dp = copy.deepcopy(a)
for i in range(n):
for j in range(i):
if a[j] < a[i]:
dp[i] = max(dp[j] + a[i], dp[i])
print(max(dp))2020fall-cs101,章斯岚。这里用i+1是为了防止a[0:i]可能是空列表导致runtime error
dp = [0]*(10000+2)
input()
for i in map(int, input().split()):
dp[i+1] = max(dp[0:i+1]) + i
print(max(dp))