1045 Favorite Color Stripe 分数 30
Eva is trying to make her own color stripe out of a given one. She would like to keep only her favorite colors in her favorite order by cutting off those unwanted pieces and sewing the remaining parts together to form her favorite color stripe.
It is said that a normal human eye can distinguish about less than 200 different colors, so Eva's favorite colors are limited. However the original stripe could be very long, and Eva would like to have the remaining favorite stripe with the maximum length. So she needs your help to find her the best result.
Note that the solution might not be unique, but you only have to tell her the maximum length. For example, given a stripe of colors {2 2 4 1 5 5 6 3 1 1 5 6}. If Eva's favorite colors are given in her favorite order as {2 3 1 5 6}, then she has 4 possible best solutions {2 2 1 1 1 5 6}, {2 2 1 5 5 5 6}, {2 2 1 5 5 6 6}, and {2 2 3 1 1 5 6}.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (≤200) which is the total number of colors involved (and hence the colors are numbered from 1 to N). Then the next line starts with a positive integer M (≤200) followed by M Eva's favorite color numbers given in her favorite order. Finally the third line starts with a positive integer L (≤104) which is the length of the given stripe, followed by L colors on the stripe. All the numbers in a line a separated by a space.
Output Specification:
For each test case, simply print in a line the maximum length of Eva's favorite stripe.
Sample Input:
6
5 2 3 1 5 6
12 2 2 4 1 5 5 6 3 1 1 5 6
题目描述
Eva用从给定地颜色条L中裁剪拼接出按顺序M排的颜色条,该颜色条的只保留她给定的颜色,且各颜色的顺序要符合她给出的优先级,求最长的序列。题目可简化为找到按指定前后顺序的最长子序列。
最初想法采用DP思路解决,即dp[i][j]表示当给出M的第i个颜色,且遍历到L的第j个颜色时,符合要求的最长子序列长度,递推条件是dp[i][j] = max(dp[i][0:j]) + M[i]==L[j]。dp[-1][-1]即是所求最大子序列长度。由于dp[i][j]递推时只需要dp中第i行和小于j列的数据,因此可以将dp[i][j]改成dp[j]。代码如下(超时问题):
n = int(input())
m = list(map(int, input().split()))
l = list(map(int, input().split()))
dp = [0] * (len(l))
for mi in m[1:]:
for i, li in enumerate(l[1:]):
if mi==li:
dp[i+1] = max(dp[0:i+1]) +1
print(dp[-1])
但是上述代码出现超时问题。由于第二层遍历中多次采用max查找前i个中的最大值,可以通过遍历时迭代更新方式确定,max步骤的时间复杂度可减到O(1)。AC代码如下:
n = int(input())
m = input().split()
l = input().split()
dp = [0] * (len(l))
ans = 0
for mi in m[1:]:
ans = 0
for i, li in enumerate(l[1:]):
if dp[i]> ans: ans = dp[i]
if mi==li:
dp[i+1]= ans+1
print(max([ans,dp[-1]]))