递归、加法原理,如何分解问题(独立且完备的划分)
生活随笔
收集整理的這篇文章主要介紹了
递归、加法原理,如何分解问题(独立且完备的划分)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
加法原理適用于做一件事有n種獨立不相交且完備的方向,每個方向上有ai種方案,則總的方案數就是 a1 + a2 +... + an
例題:把n個數分為k個非空子集,有多少種分法?
分解問題:第一個集合里放多少個數把原問題的解分成了獨立且完備的若干方向,分別解每個方向上的方案數,然后相加
memo = [[-1] * (1000) for i in xrange(1001)] def group(n, k):if k == 0: return 1 if n == 0 else 0if memo[n][k] > 0: return memo[n][k]ans = 0for i in xrange(1, n - (k - 1) + 1):ans += group(n - i, k - 1) * C(n, i)memo[n][k] = ansreturn ans還有一種形式的加法原理,適用于最優解問題,還是原問題劃分為若干獨立且完備的方向,每個方向上的最優解中取最優的。比如背包問題,第一個物品取或不取就是這樣一種獨立且完備的劃分,全局最優解就是這兩種情況下的最優解中最優的那個
def backpack(V, W, C, i):if i == len(V) or C == 0: return 0ans = backpack(V, W, C, i + 1)if W[i] <= C: ans = min (ans, backpack(V, W, C - W[i], i + 1));return ans;分組問題:n個數分成k組,打印所有的方案
如何劃分問題:當前數數分到哪個組作為劃分,然后遞歸問題。注意剪枝去重和排除空集。去重:盡量往前堆
def group(A, k):groups = [[] for i in xrange(k)]def dfs(i, allocated):if i == len(A) and allocated == k: print groupselif k - allocated <= len(A) - i:for j in xrange(k):groups[j].append(A[i])dfs(i + 1, allocated + 1 if len(groups[j]) == 1 else allocated)groups[j].pop()if len(groups[j]) == 0: breakdfs(0, 0)分組問題的應用POJ1011:給定一組小棍子的長度,拼接一組等長的大棍子,求最小的等長長度。
分析:枚舉可能的長度,最小為小棍子中最長的那根,最大為所有棍子拼成一根大棍子的長度,這個長度值還必須能被總長度整除(只考慮整數長度)
對于每個可能的長度len,嘗試對小棍子進行分組,條件是組長度不能超過len,如果最后能分完,每個組的長度都 <= len, 則其實都是==len,否則如果有小于len的必然就有>大于len的。
def minEqualtick(A):minLen, total, lower = [sum(A)], sum(A), max(A)for l in xrange(lower, total):if total % l != 0: continuek, groups = total / l, [0] * (total / l)def group(i):if i == len(A): minLen[0] = lelse:for j in xrange(0, k):if groups[j] <= l - A[i]:groups[j] += A[i]group(i + 1)groups[j] -= A[i]if groups[j] == 0: breakgroup(0)return minLen[0], total / minLen[0], total?總結
以上是生活随笔為你收集整理的递归、加法原理,如何分解问题(独立且完备的划分)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Xposed之开发Hook插件
- 下一篇: excel2016中怎么开启宏?exce