设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。
输入格式:
输入有两行:
第一行:n,代表要输入的数列的个数
第二行:n个数,数字之间用空格格开
输出格式:
最长单调递增子序列的长度
输入样例:
在这里给出一组输入。例如:
5
1 3 5 2 9
输出样例:
在这里给出相应的输出。例如:
4
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
n = int(input())
nums = list(map(int, input().split()))
dp = [1] * n
for i in range(n):
for j in range(i):
if nums[j] < nums[i]:
dp[i] = max(dp[i], dp[j]+1)
print(max(dp))
这段代码实现了动态规划中最长递增子序列问题的状态转移方程。具体而言,它表示以第 i 个数字结尾的最长递增子序列的长度可以通过枚举 i 前面的数字 j,找出那些比 nums[i] 小的数字,然后尝试将这些数字加入到以 j 结尾的最长递增子序列中,从而生成以 i 结尾的更长的最长递增子序列。具体而言,如果 nums[j] < nums[i],那么以 j 结尾的最长递增子序列可以扩展到以 i 结尾的最长递增子序列,此时更新 dp[i] 的值为 dp[j]+1,表示将 nums[i] 加入到以 j 结尾的最长递增子序列中能够生成长度为 dp[j]+1 的新的最长递增子序列,然后取 dp[i] 和 dp[j]+1 中的最大值,更新 dp[i] 的值。这样,当 i 枚举完整个序列后,dp 数组中的最大值即为最长递增子序列的长度。因此,该代码段可以写作:
dp[i] = max(dp[i], dp[j]+1)
其中 dp[i] 表示以第 i 个数字结尾的最长递增子序列的长度,dp[j] 表示以第 j 个数字结尾的最长递增子序列的长度,如果 nums[j] < nums[i],那么将 nums[i] 加入到以 j 结尾的最长递增子序列中能够生成长度为 dp[j]+1 的新的最长递增子序列,更新 dp[i] 的值为 dp[j]+1 和 dp[i] 中的较大值。