解法
解法一:基本DP
基本思想是维护一个数组f[i]f[i]f[i]表示使用i次操作时能得到的最大长度
- 假如最后一次是多加一个
A
,那么得到长度f[i-1]+1
- 最后的操作是连续k个粘贴,那么
全选+复制+k个粘贴
一共k+2
个操作,能得到f[i-(k+2)]*(k+1)
长度
那么,状态转移方程就是从这里面取最大值,时间复杂度为O(N)
class Solution:
def maxA(self, N: int) -> int:
# from functools import lru_cache
from collections import defaultdict
f = [0]
for i in range(1,N+1):
f.append(f[i-1]+1)
for j in range(1,i-2):
f[i] = max(f[i],f[i-j-2]*(j+1))
return f[-1]
解法二:优化的DP
如果我们想对长度为L的字符串连续粘贴2k-1
次,那么我们将执行2k+1
次操作,最终得到长度为L*2k
的字符串
但是我们同样可以先连续粘贴k-1
次,得到长度为L*k
的字符串后,再复制粘贴一次,这样会使用k+4
次操作
当k>=3
时,后者永远步数更少,所以我们完全没有必要考虑连续粘贴2*3-1=5
次及以上的情况
也就是子循环只要循环4次即可
class Solution:
def maxA(self, N: int) -> int:
# from functools import lru_cache
from collections import defaultdict
f = [0]
for i in range(1,N+1):
f.append(f[i-1]+1)
for j in range(1,min(i-2,5)):
f[i] = max(f[i],f[i-j-2]*(j+1))
return f[-1]
解法三:数学推导
……看不懂solution= =