题目如下:
题目分析:
考虑如果不要求任意能改变看个数,最长不降子序列是如何求解。
tips:什么是不下降子序列。
就是从原序列中选出子序列(顺序不发生改变)。如果按顺序后面的数都大于等于前面一个数,那它就是不下降的子序列。
动态规划dp:假设有一数组a 为原序列,一数组dp 长为len(a)dp【i】的意思为以 a 结尾的不下降子序列的长度。
1、如何求dp【i】呢?
首先我们给dp赋予初始值1。即代表每一个数据为结尾的子序列的长度都为1(即是自身)。
对于dp【i】:我们可以对比前面的每一位数的大小。若a[ j ]<= a[ i ],则dp[ i ] = max( dp[ i ], dp[ j ] + 1) 。
这个看以下代码就理解了。
a = [1, 4, 2, 8, 5]
dp = [1, 1, 1, 1, 1]
for i in range(len(a)):
for j in range(i): ## j 不能等于i
if a[j]<=a[i]: # 前面有一项是小于等于a[i]时
dp[i] = max(dp[i], dp[j]+1)
else:
continue
print(max(dp))
我确实讲不清除,不过,自己写写应该就懂了。
对于能改变的序列我们该怎么求呢?
去除不同位置长度为k的段,然后找最大值。???(可以是可以,不过上了个大当,这随便一算就得超时呀,但是我还是这样写了hhh)。
代码:
去除段的(辣鸡代码,有一个小错误我还调试了好久)
n, k = map(int, input().split())
m = list(map(int, input().split()))
fin_max = 0
for i in range(n - k + 1): # 这是断续点的起始位置
a = [1 for _ in range(n)] # 先设置前n位的最大的不减子序列为 1(就是自身)
for j in range(n): # 这是dp要得到结果的指针
for it in range(j): # 这是dp前面的指针
if j in range(i, i + k) or it in range(i, i + k): # j 与 it 不能取位于去除地方的数字
continue
if m[j] >= m[it]:
a[j] = max(a[j], a[it] + 1) # dp结果
fin_max = max(fin_max, max(a) + k)
print(fin_max)
换换脑子,题目要求我们讲连续的k个数换为任意一个相同的值。
假设我们求到了原数据中的最长子序列,那么我们这k长度的替换值一定要是与最长子序列重复最少的,或者是不是最长子序列的。
哎呀,想不明白了。寄了得是,有人看到这里的话踢踢我。让我重新再写写。