1. 程式人生 > >練習題 No.10 多重部分和問題

練習題 No.10 多重部分和問題

要求

有n種不同大小的數字ai,每種個mi個。判斷是否可以從這些數字之中選出若干使他們的和恰好為K。

限制條件

  • (1 <= n <= 100)
  • (1 <= ai, mi <= 100000)
  • (1 <= K <= 100000)

輸入格式

第一行輸入n
接下來n行輸入ai,mi
最後一行輸入K

輸出格式

如果有,則輸出YES, 如果無,則輸出NO

測試輸入

3
3 3
5 2
8 2
17

測試輸出

YES

解題思路

使用dp陣列來存剩餘數量個數,下標用來記錄當前和。

程式碼

#include <iostream>  
#include <cstring> using namespace std; int dp[100001]; int main() { int n; cin >> n; int a[101],m[101]; for (int i = 0; i < n; i++) { cin >> a[i] >> m[i]; } int K; cin >> K; memset(dp, -1, sizeof(dp)); dp[0] = 0; for (int
i = 0; i < n; i++) { for (int j = 0; j <=K; j++) { if (dp[j] >= 0) { dp[j] = m[i]; } else if (j < a[i] || dp[j - a[i]] <= 0) { dp[j] = -1; } else { dp[j] = dp[j - a[i]] - 1; } } } if
(dp[K] >= 0) { cout << "YES" << endl; } else { cout << "NO" << endl; } return 0; }