問題描述:這道題是一道動態規劃的揹包,我們以上面的輸入輸出為例給定乙個有n個正整數的陣列a和乙個整數sum,求選擇陣列a中部分數字和為sum的方案數。
當兩種選取方案有乙個數字的下標不一樣,我們就認為是不同的組成方案。
輸入描述:
輸入為兩行: 第一行為兩個正整數n(1 ≤ n ≤ 1000),sum(1 ≤ sum ≤ 1000)第二行為n個正整數a[i](32位整數),以空格隔開。
輸出描述:
輸出所求的方案數
示例1輸入
5 15
5 5 10 2 3
輸出
首先,將輸入的資料放到乙個一維陣列裡,我這裡使用的是vector,都一樣
注意: 下標為0的位置跳過,這個位置預設值為0,我們的資料從下標為1的位置開始
下標v[i]
接下來我們構建乙個二維陣列,由於這個題目給出的n,sum的範圍都是 1000,於是我們構建乙個 1001*1001的二維陣列dp
注意: 這個陣列不要構建在棧上,這個空間可能很大,這裡要求的是1000,有的題目會要求5000,難道要在棧上構建乙個 5001*5001*sizeof(int) 大小的空間嗎
所以這裡建議將這個陣列定義在全域性區或者在對上動態開闢,不過我覺得在全域性區上使用起來比較簡單
p[i]
舉乙個例子:
比如圖中黃色的點,他的座標為 (2,2), 表示的意思為我們現在擁有質量為 v[0](也就是0)的物品和質量為v[1](也就是5)的物品 (注意,這裡只要小於等於當前行的物品我們都可以看作是擁有的),我們需要組合成乙個質量為5(也就是當前列的下標)的揹包,黃色格仔處填的就是方法數
p[i]
我們可以理解為
p[i]
可以理解為
迴圈條件:情況一: 新增物品的質量(v[i]) 大於所需要合成揹包的質量 jfor(int i = 1; i <= n; ++i)
}
這時候揹包已經裝不下新的物品了,所以可裝的物品應該不變,即繼承了上一行的值即可 -> dp[i][j] = dp[i-1][j]
情況二: 新增的物品質量小於等於需要合成揹包的質量 j
先給出結論: dp[i][j] = dp[i-1][j] + dp[i-1][j- p[i] ]
我們以第二行為例:
這一行我們新增的物品質量為 5(p[1])
所有 j < 5 的列 (紫色) ,我們都不可以將 5再次加到揹包中,於是就繼承上一行的值
所有 j >= 5的列 (黃色), 都有可能和之前有過的物品組合成當前的列值, 比如: 座標為[1][5]這乙個格仔(亮黃色),我們新增了乙個質量為5的物品,之前有乙個質量為0的物品,組合起來就可以構成乙個質量為5的揹包
p[i]
上面情況二的例子不夠明顯,這次我們以座標為 [5][10]舉例;
當前我們所擁有的物品質量: 0,5,5,10,2,3
我們所要合成的揹包質量: 10
假設我們已經知道當我們只有 0,5,5,10,2的物品時,有兩種合成方法(即當前行的上一行)
當我們新增了乙個質量為3的物品時,只要知道了之前有多少種組合可以構成質量為7的揹包
現在可構成質量為10 的揹包的方法數 = 上一行構成10的值 + 上一行構成7的值
即: 2 + 2 = 4種
p[i]
這道題我們所要求解的是和為sum的方法數,即找 [n][sum] 這一點對應的值即可
#include using namespace std;
#include #include #include int dp[1001][1001];
int digit_sum(int n,int sum,vector& v)
// 2. dp第一行全部賦值為0
for(int j = 1; j <= sum; ++j)
// 3. 根據上一行的值算出當前位置的值
for(int i = 1; i <= n; ++i)
else}}
return dp[n][sum];
}int main()
int res = digit_sum(n,sum,v);
cout
}
動態規劃 數字和為sum的方法數
題目描述 給定乙個有n個正整數的陣列a和乙個整數sum,求選擇陣列a中部分數字和為sum的方案數。當兩種選取方案有乙個數字的下標不一樣,我們就認為是不同的組成方案。輸入描述 輸入為兩行 第一行為兩個正整數n 1 n 1000 sum 1 sum 1000 第二行為n個正整數a i 以空格隔開。輸出描...
數字和為sum的方法數
給定乙個有n個正整數的陣列a和乙個整數sum,求選擇陣列a中部分數字和為sum的方案數。當兩種選取方案有乙個數字的下標不一樣,我們就認為是不同的組成方案。輸入描述 輸入為兩行 第一行為兩個正整數n 1 n 1000 sum 1 sum 1000 第二行為n個正整數ai,以空格隔開。輸出描述 輸出所求...
求解數字和為 sum 的方法數問題
問題描述 給定乙個有 n 個正整數的陣列 a 和乙個整數 sum,求選擇陣列 a 中部分數字和為 sum 的方案數。若兩種選區方案有乙個數字的下標不一樣,則認為是不同的方案。輸入描述 輸入為兩行,第 1 行為兩個正整數 n sum,第 2 行為 n 何正整數 a i 以空格 隔開。輸出描述 輸出所求...