SPOJ Alphcode迭代动态规划

时间:2013-11-26 13:35:16

标签: python algorithm dynamic-programming

我能够使用递归DP解决标题中给出的问题,但得到了TLE。这是因为输入字符串可以有大约5000个数字,这会导致很多子函数调用,并且我的程序无法计算结果,即使在我的计算机上也是如此。

问题如下: ACODE

我的解决方案如下:

import sys

def chk(word):
    if word[0] == '0':
        return 0
    if int(word) < 27 and int(word) > 0:
        return 1
    else:
        return 0

def dp(line):
    if len(line) > 2:
        return chk(line[0])*dp(line[1:]) + chk(line[:2])*dp(line[2:])
    elif len(line) > 1:
        return chk(line[0])*dp(line[1]) + chk(line)
    else:
        return chk(line)

line = sys.stdin.readline().strip()
while line != '0':
    print dp(line) 
    line = sys.stdin.readline().strip()

搜索互联网可以得到以下解决方案:

  

1)初始化一个大小为N的数组,其中0和元素0为1   2)循环遍历所有元素
  3)如果是有效的单个数字,则将前一个元素的值复制到当前元素(DP [i] = DP [i-1])
  4)如果它是有效的两位数,则将前一个元素的值的前一个值添加到当前元素(DP [i] + = DP [i-2])

     

在一行中:DP [i] = DP [i-1] {如果有效的单位数字} + DP [i-2]   {如果当前和以前的元素生成有效的两位数字}

我不确定我是否也在做同样的事情,因为我无法理解上述方法,或者是否有某种方法可以将我的递归方法转变为迭代方法。

2 个答案:

答案 0 :(得分:1)

该算法遵循动态规划方法。

它只是从左到右扫描代码字符串。

随着字符串长度的增加,可能性的数量也会增加。

每个新数字都有两种可能性。如果它是有效数字,那么新的可能性数量至少等于前一个数字的可能性。

此外,如果新数字和prev-digit产生一个数字> = 11且<= 26,则可能性的数量增加(可能性高达I-2)

Example if the number is 2134

A[0] = 1.
second digit is 1. Hence A[1] is at least = A[0] = 1. 
Also, 21 can make a valid character code as well. 
Hence, A[1] becomes 1 + 1 = 2.

The two strings possible upto A[1] are 2,1 and 21.

Third digit is 3. Hence A[2] is at least = A[1] = 2. 
Also, 13 can make a valid character code.
Hence additional possibilities can result if we consider 13 as a single character = A[2].
Hence A[3] = 2 + 1 = 3 ({2,1,3}, {21,3}, {2,13})

Simililarly for A[4].

答案 1 :(得分:0)

2个非常小的修改(不会提高效率,但更多pythonic&amp;更好)

def chk(word):
    if word[0] == '0':
        return 0
    elif 0 < int(word) < 27: # notice the elif & multiple comparisons
        return 1
    else:
        return 0