【发布时间】:2021-05-25 17:14:21
【问题描述】:
我有一个字符串S,只包含两个字符“x”和“y”。我还有一个与S 长度相同的正整数数组A。如果该子字符串具有所有相同的字符,我可以删除任何正长度(> 0)的子字符串。这一步的得分是A[len],其中len是删除的子字符串的长度,索引是从1开始的(因为我们不能删除长度为0的子字符串)。我可以进一步删除这些子字符串,直到它变空并且分数将继续增加。我想最大化这个分数。没有必要尽量减少移动次数。
例如,设 S = "xyy" and A = [2,3,1];我可以选择子字符串 S[1:2]="yy",结果字符串将是 "x",分数是 3;现在我可以选择 S[0:0]="x",结果字符串是 "",分数是 5;
另一种方法是,选择S[0:0],结果字符串为“yy”,得分为2;选择S[0:0],结果字符串为“y”,得分为4;选择S[0 :0],结果字符串是"",分数是6,比以前高。
我想不出一个贪婪的解决方案,所以尝试了蛮力:
# Checks if the chosen substring has all same characters or not
def check(s):return True if len(set(s)) == 1 else False
def cost(s):
n = len(s)
if n == 0:return 0
if n == 1:return a[0]
mx = -1
# Try to remove all the substrings that satisfy the condition
# And further check for resultant string after removal
for i in range(n):
for j in range(i,n):
sub = s[i:j+1]
if check(sub):mx = max(mx, a[len(sub)-1] + cost(s[:i]+s[j+1:]))
return mx
此解决方案适用于长度不超过 8 的字符串,否则会卡住(基于我的系统配置),因此我在其中添加了记忆:
# Checks if the chosen substring has all same characters or not
def check(s):return True if len(set(s)) == 1 else False
dp = dict()
def cost(s):
# If this string is present in dp, return score
if s in dp:return dp[s]
n = len(s)
if n == 0:return 0
if n == 1:return a[0]
mx = -1
# Try to remove all the substrings that satisfy the condition
# And further check for resultant string after removal
for i in range(n):
for j in range(i,n):
sub = s[i:j+1]
if check(sub):mx = max(mx, a[len(sub)-1] + cost(s[:i]+s[j+1:]))
dp[s] = mx
return mx
它适用于长度不超过 20 的字符串。它满足我目前的要求,但可以进一步优化吗?它只是一种蛮力解决方案,因此对于长度超过 20 的字符串看起来不太令人满意。
能否优化到多项式时间O(N^2)或O(N^3)?
【问题讨论】:
标签: python string algorithm recursion binary