【发布时间】:2018-12-27 23:47:50
【问题描述】:
假设您有一个带有以下键的特殊键盘:
键 1:(A):在屏幕上打印一个“A”。
键 2:(Ctrl-A):选择整个屏幕。
键 3:(Ctrl-C):将选择复制到缓冲区。
键 4:(Ctrl-V):在屏幕上打印缓冲区,将其附加在已完成的内容之后 已经打印出来了。
现在,你只能按键盘N次(以上四次 键),找出您可以在屏幕上打印的“A”的最大数量。
示例 1:
输入:N = 3
输出:3
说明:我们最多可以通过按以下键序列在屏幕上获得3个A:A, A, A
示例 2:
输入:N = 7
输出:9
说明:我们最多可以通过按以下键序列在屏幕上获得 9 个 A:A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V
(免责声明:我不想听到不同的解决方案。我只想了解我缺少什么以及如何解决它。)
这是我当前的(不正确的)解决方案(解释如下):
class Solution:
def maxA(self, N):
screen = [0] * N
screen[0] = 1
applied_clipboard = clipboard = select = 0
for i in range(1, N):
if i < 3:
screen[i] = screen[i-1] + 1
else:
screen[i] = max(screen[i-3] + clipboard, screen[i-1] + 1, screen[i-1] + applied_clipboard)
if screen[i] == screen[i-3] + clipboard:
applied_clipboard = clipboard
select, clipboard = max(select, screen[i-1]), max(clipboard, select)
return screen[-1]
如您在上面的代码中所见,我正在跟踪一些状态。状态是:
- 我选择了多少个字符?
- 我在屏幕上打印了多少个字符?
- 我的剪贴板中有多少个字符?
- 我实际应用的最新剪贴板是什么?
有了这些状态,我相信我可以在每一步做出最佳决策。
但是,我的代码不正确。对于N = 11的输入,我的代码返回27,正确值为27。但是,对于N=9 和N=10,正确的值是16 和20(分别),但我得到15 和18(分别)。
有人看到我更新状态的方式中的错误吗?
编辑。回应现有答案: 我知道我的状态更新可能不完整,但问题是在哪里。我的想法是保持每个状态最大化,因为有一系列单独的决策来最大化每个状态。然后,使用所有这些信息来更新下一次迭代中的状态。
重写了我的代码以保留每个部分的状态。
class Solution:
def maxA(self, N):
screen = [0] * N
screen[0] = 1
applied_clipboard, clipboard, select = [[0] * N for _ in range(3)]
for i in range(1, N):
if i < 3:
screen[i] = screen[i-1] + 1
else:
screen[i] = max(screen[i-3] + clipboard[i-1], screen[i-1] + 1, screen[i-1] + applied_clipboard[i-1])
if screen[i] == screen[i-3] + clipboard[i-1]:
applied_clipboard[i] = clipboard[i-1]
else:
applied_clipboard[i] = applied_clipboard[i-1]
select[i] = max(select[i-1], screen[i-1])
clipboard[i] = max(clipboard[i-1], select[i-1])
print('screen', screen)
print('clipboard', clipboard)
print('applied', applied_clipboard)
return screen[-1]
我认为我在这里感到困惑的是如何保留已应用的剪贴板值 (applied_clipboard) 与最大剪贴板状态。但我需要区分两者,因为它会影响递归关系。
感谢user3386109 引导我看到:
-
N=9的正确步骤是AAAASCVVV(总共 16 个 A) - 我的代码,对于
N=9,输出AAASCVVVV(总共 15 个 A)。
其中 s = 选择,c = 复制,v = 粘贴。
【问题讨论】:
-
您的“免责声明”是什么意思?也许不同的解决方案会更容易阅读并且更不容易出现错误。也许您的解决方案是错误的,因此需要“不同”的正确解决方案。
-
当你得到解决方案时,请记得给有用的东西投票并接受你最喜欢的答案(即使你必须自己写),这样 Stack Overflow 才能正确存档问题。跨度>
标签: python algorithm dynamic-programming