动态规划算法-05KSum问题
生活随笔
收集整理的這篇文章主要介紹了
动态规划算法-05KSum问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
KSum問題
- 簡述
- CCF、LeetCode這類程序設計競賽的常見題型。
- 問題描述
- 給定一個n個數字的序列(均為整數),求k個數字的和為target的情況有多少種?
- 注意,這里是依據下標選數,也就是說兩種情況三個數字一樣但是有一個數字的下標在兩個情況中不一樣,那么算作兩種情況。
- 這種題目只要一個最后結果可以使用遞歸迅速解答,本質上是在填一個二維表;如果要輸出所有情況,本質上是填一個三維表。
- 問題分析
- F(n,k,target)表示n個數里面選k個數和為target的情況數目。
- n個數字里面k個數的和是否為target,可以分為兩種情況:第n個數字被選了=F(n-1,k-1,target-nums[n]);第n個數字沒有選=F(n-1,k,target)。結果是這兩種情況的和。可以依次類推下去。
- 得到邊界和狀態轉移函數為
- F(n,k,target)=0;n<k
- F(n,k,target)=0;n=0 or k = 0
- F(n,k,target)=m; k=1(m為從0到n的元素中值為target的元素個數)
- F(n,k,target)=F(n-1,k-1,target-nums[n])+F(n-1,k,target);n>=k
- 由此,不難寫出遞歸思路的代碼。
- 代碼
- def dp(n, k, target, nums_list, rst):number_list = nums_listif k > n:return 0if n == 0 or k == 0:return 0if k == 1:for i in range(n):if number_list[i] == target:rst += 1return rstif n >= k:return dp(n-1, k-1, target-number_list[n-1], number_list, rst) + dp(n-1, k, target, number_list, rst)if __name__ == '__main__':nums = [1, -1, 0, 1]n = len(nums)k = 3target = 0out = 0# 對這個題目而言就是填寫dp[n][[k]的表格print(dp(len(nums), 3, 0, nums, out))
- 補充說明
- 這種遞歸做法雖然可以迅速解答,但是不利于填表去回溯查找每種情況的具體取值,后面會使用循環填表來完成這一題。
- 具體代碼和更多算法類問題見我的Github,歡迎Star或者fork。
總結
以上是生活随笔為你收集整理的动态规划算法-05KSum问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 动态规划算法-04最长递增子序列问题
- 下一篇: 动态规划算法-06Longest Val