fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5. typedef pair<int, int> ii;
  6.  
  7. template<typename T>
  8. bool maximize(T& a, const T& b) {
  9. if (b < a) return false;
  10. a = b;
  11. return true;
  12. }
  13.  
  14. const int INF = 1e9;
  15. const ll LINF = 1e18;
  16.  
  17. // dp knapsack
  18. // Biến thể: mỗi món vật có thể được chọn nhiều lần
  19.  
  20. const int N = 1e2 + 5;
  21. const int S = 1e6 + 5;
  22. const int MOD = 1e9 + 7;
  23.  
  24. int n, s;
  25. int w[N];
  26. int dp[S]; // dp[i][j] = số cách chọn các món vật trong i món vật đầu tiên sao cho tổng = j
  27. // 1 món có thể chọn nhiều lần
  28.  
  29. int memo[N][S];
  30.  
  31. int f(int i, int j) {
  32. if (i == 0) {
  33. if (j == 0) return 1;
  34. return 0;
  35. }
  36.  
  37. int& ans = memo[i][j];
  38. if (ans != -1) return ans;
  39.  
  40. // không chọn món vật thứ i
  41. ans = f(i - 1, j);
  42.  
  43. // chọn món vật thứ i
  44. if (j - w[i] >= 0) (ans += f(i, j - w[i])) %= MOD;
  45.  
  46. return ans;
  47. }
  48.  
  49. int main() {
  50. ios::sync_with_stdio(0); cin.tie(0);
  51. cin >> n >> s;
  52. for (int i = 1; i <= n; i++) {
  53. cin >> w[i];
  54. }
  55.  
  56. dp[0] = 1;
  57. // O(n * S)
  58. for (int i = 1; i <= n; i++) {
  59. for (int j = 0; j <= s; j++) {
  60. // chọn món vật thứ i
  61. if (j - w[i] >= 0) {
  62. (dp[j] += dp[j - w[i]]) %= MOD;
  63. }
  64. }
  65. }
  66.  
  67. cout << dp[s] << '\n';
  68.  
  69. // memset(memo, -1, sizeof memo);
  70.  
  71. // cout << f(n, S) << '\n';
  72. }
Success #stdin #stdout 0.01s 5556KB
stdin
3 9
2 3 5
stdout
3