如果没记错的话,在《C名题精选百则》中出现过这题。我们可以考虑更普遍的情况,将正整数N分解成不超过M的整数和的情况。 对于这种情况,可以将分解分成包含整数M和不包含整数M的情况。令f(N,M)为总共的分解方式,则 f(N,M) = f(N - M, M) + f(N, M -1),于是写成程序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
defpartition(n): return _partition(n, n)
def_partition(n, m): if n == 0: return1 if n < 0: return0 if m == 1: return1 else: return _partition(n - m, m) + _partition(n, m - 1) for i in xrange(1, 10): print i, partition(i)
只是当n比较大时,递归的效率太慢了,于是用动态规划重写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
defpartition(n): dp = [[0for i in xrange(n + 1)] for j in xrange(n + 1)] for i in xrange(n + 1): dp[i][1] = 1 dp[0][i] = 1 for i in xrange(1, n + 1): for j in xrange(1, n + 1): if i - j >= 0: dp[i][j] = dp[i - j][j] + dp[i][j - 1] else: dp[i][j] = dp[i][j - 1] return dp[n][n]
defgetPrimes(n): primes = [Truefor i in xrange(n + 1)] primes[0] = primes[1] = False for x in xrange(2, n + 1): ifnot primes[x]: continue m = x * x while m <= n: primes[m] = False m += x return [i for i in xrange(n + 1) if primes[i]]
print get_primes(100)
2014年8月16日更新: 才发现这个函数的速度还不理想,于是改成
1 2 3 4 5 6 7 8 9
defgetPrimes(n): primes = [True] * (n + 1) primes[0] = primes[1] = False i = 2 while i * i <= n: if primes[i]: primes[i * i:n + 1:i] = [False] * ((n - i * i) / i + 1) i += 1 return [i for i in xrange(n + 1) if primes[i]]
L=[2,8,3,50] length = len(L) count = 0 for i in xrange(length): minum = L[i] index = i for j in xrange(i + 1, length): if L[j] < minum: minum = L[j] index = j if index != i: L[i],L[index] = L[index],L[i] count += 1 print count
defegg(n, e=2): dp = [[n for i in xrange(e + 1)] for j in xrange(n + 1)] for i in xrange(1, n + 1): dp[i][1] = i for i in xrange(1, e + 1): dp[1][i] = 1 dp[2][i] = 2 for i in xrange(3, n + 1): for j in xrange(2, e + 1): for r in xrange(1, n): dp[i][j] = min(dp[i][j], 1 + max(dp[i - r][j], dp[r - 1][j - 1]))
取石子游戏说的是有两堆任意数量的小石子,游戏由两个人轮流取石子,对于取法,游戏规定有两种,一种是可以在任意的一堆中,取走任意多的石子;一种是在两堆中同时取走相同数量的石子。游戏规定,最后把石子全部取完的为胜者。现在假设初始时两堆石子的数目为a和b, a <= b,假设双方都采取最好的策略,问先取的人是胜者还是败者。
defedit_distance(a, b): la = len(a) lb = len(b) dp = [[0for i in xrange(lb + 1)] for j in xrange(la + 1)] for i in xrange(1, la + 1): dp[i][0] = i for j in xrange(1, lb + 1): dp[0][j] = j for i in xrange(la): for j in xrange(lb): if a[i] == b[j]: dp[i + 1][j + 1] = dp[i][j] else: dp[i + 1][j + 1] = min(dp[i + 1][j], dp[i][j + 1], dp[i][j]) + 1 return dp[la][lb]