題目描述
給定乙個有n個正整數的陣列a和乙個整數sum,求選擇陣列a中部分數字和為sum的方案數。
當兩種選取方案有乙個數字的下標不一樣,我們就認為是不同的組成方案。
輸入描述:
輸入為兩行:
第一行為兩個正整數n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)
第二行為n個正整數ai,以空格隔開。
輸出描述:
輸出所求的方案數
分析:第一種方法是遞迴(深度優先遍歷),雖然會超時,但是思路依然值得寫下來
方法一思路:首先是第一層for迴圈,對陣列中每乙個數進行深度優先遍歷,然後是第二層for迴圈,對於當前的數,對陣列中每個在其後的數進行檢測,若它們(當前的數與其後的數的和)的和小於m,則繼續遞迴,否則退出。在每次遞迴的一開始就檢測當前的和是否等於m,以判斷是否cnt+1。
**如下:
def
getcount
(n, m, i, sum):
global a
global cnt
if(sum == m):
cnt += 1
return
for j in range(i + 1, n):
if(sum < m):
getcount(n, m, j, sum+a[j])
else:
return
n, m = map(int, raw_input().split())
a = map(int, raw_input().split())
a = sorted(a)
cnt = 0
for i in range(n):
getcount(n, m, i, a[i])
print cnt
若要不超時,就要用動態規劃了。
方法二:動態規劃。令dp[i][j]表示前i個數中和為j的組合的個數,則當j>=a[i]時,前i個數和為j的組合個數=前i-1個數中和為j的j的組合的個數+前i-1個數中和為j-a[i]的組合個數。
**如下:
from numpy import *
import numpy as np
dp = np.zeros((1010, 1010))
defgetcount2
(n, m):
global a2
dp[:,0] = 1
for i in range(1,n + 1):
for j in range(1, m + 1):
if(j >= a2[i]):
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - a2[i]]
else:
dp[i][j] = dp[i - 1][j]
n, m = map(int, raw_input().split())
a = map(int, raw_input().split())
a2 = sorted(a)
a2.insert(0,0)
getcount2(n, m)
print dp[n][m]
牛客 數字和為sum的方法數(滴滴筆試)
程式設計題 數字和為sum的方法數 給定乙個有n個正整數的陣列a和乙個整數sum,求選擇陣列a中部分數字和為sum的方案數。當兩種選取方案有乙個數字的下標不一樣,我們就認為是不同的組成方案。輸入描述 輸入為兩行 第一行為兩個正整數n 1 n 1000 sum 1 sum 1000 第二行為n個正整數...
牛客網 和為sum的所有組合方案
include include include include includeusing namespace std 題目描述 輸入兩個整數 n 和 m,從數列1,2,3.n 中隨意取幾個數,使其和等於 m 要求將其中所有的可能組合列出來 分析思路 採用深度優先搜尋,一旦搜尋到滿足條件的組合,就輸出...
數字和為sum的方法數
給定乙個有n個正整數的陣列a和乙個整數sum,求選擇陣列a中部分數字和為sum的方案數。當兩種選取方案有乙個數字的下標不一樣,我們就認為是不同的組成方案。輸入描述 輸入為兩行 第一行為兩個正整數n 1 n 1000 sum 1 sum 1000 第二行為n個正整數ai,以空格隔開。輸出描述 輸出所求...