整数拆分问题

【问题描述】:
求将正整数n无序拆分成最大数为k的拆分方案个数,要求所有的拆分方案不重复。
【问题求解】:
n = 5, k = 5, 对应的拆分方案如下:
5 = 5
5 = 4 +1
5 = 3 + 2
5 = 3 + 1 + 1
5 = 2 + 2 + 1
5 = 2 + 1 + 1 + 1

一、递归法
根据n和m的关系,考虑下面几种情况:
(1)当n=1时,不论m的值为多少(m>0),只有一种划分,即{1};
(2)当m=1时,不论n的值为多少(n>0),只有一种划分,即{1,1,…1,1,1};
(3)当n=m时,根据划分中是否包含n,可以分为两种情况:
(a)划分中包含n的情况,只有一个,即{n};
(b)划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有(n-1)划分;
因此,f(n,n) = 1 + f(n, n - 1)。
(4)当n (5)当n>m时,根据划分中是否包含m,可以分为两种情况:
(a)划分中包含m的情况,即{m,{x1,x2,x3,…,xi}},其中{x1,x2,x3,…,xi}的和为n-m,可能再次出现m,因此是(n-m)的m划分,因此这种划分个数为f(n-m, m);
(b)划分中不包含m的情况,则划分中所有值都比m小,即n的(m-1)划分,个数为f(n, m - 1);
因此,f(n,m) = f(n - m,m) + f(n, m - 1)。

def GetPartitionCount(n,m):
    if n == 1 or m == 1:
        return 1
    elif n < m:
        return GetPartitionCount(n,n)
    elif n == m:
        return 1 + GetPartitionCount(n,n-1)
    else:
        return GetPartitionCount(n-m,m) + GetPartitionCount(n,m-1)

二、动态规划

def GetPartitionCount(n,m):
    for i in range(1,n+1):
        for j in range(1,m+1):
            if j == 1 or i == 1:
                dp[i][j] = 1
            elif i == j:
                dp[i][j] = dp[i][j-1]+1
            elif i<j:
                dp[i][j]=dp[i][i]
            else:
                dp[i][j]=dp[i-j][j]+dp[i][j-1]
    return dp[n][m]

三、给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

def integerBreak(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    elif n == 2:
        return 1
    else:
        dp = [0 for _ in range(n+1)]
        dp[0] = 0
        dp[1] = 1
        dp[2] = 1
        for i in range(3,n+1):
            tmp = 0
            for j in range(1,i):
                tmp = max(tmp,max(j * dp[i - j],j*(i-j)))
            dp[i] = tmp
        return dp[n],dp

你可能感兴趣的:(Coding)