这是一道典型的 0/1 背包问题,可以使用动态规划进行解决。
我们可以定义一个二维数组 dp[i][j],其中 i 表示前 i 个产品,j 表示金额数。dp[i][j] 表示使用 j 元钱购买前 i 件物品的方案数。
则有状态转移方程:dp[i][j] = dp[i-1][j] + dp[i-1][j-v[i]],其中 v[i] 表示第 i 个产品的价格。意思是,当不购买第 i 个产品时,方案数为 dp[i-1][j];当购买第 i 个产品时,方案数为 dp[i-1][j-v[i]]。
最终答案为 dp[n][m]。
注意在计算过程中要对 20232023 取模,防止答案大于该数。
在修改 dp[i][j] 的值时,应该加上 dp[i][j] 自身的值。因为 dp[i-1][j-v[i]] 表示选了第 i 件物品后,剩余的总价值是 j-v[i] 的方案数,而 dp[i][j] 表示在不选第 i 件物品的前提下,总价值是 j 的方案数,所以需要将这两个方案数相加才能得到总方案数。
#include <iostream>
using namespace std;
const int MOD = 20232023;
const int MAX_N = 105;
const int MAX_M = 10005;
int n, m;
int v[MAX_N];
int dp[MAX_N][MAX_M];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> v[i];
}
dp[0][0] = 1;
for (int i = 1; i <= n; i++) {
dp[i][0] = 1;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dp[i][j] = dp[i-1][j];
if (j >= v[i]) {
dp[i][j] = (dp[i][j] + dp[i][j-v[i]]) % MOD; // 修改加号为加上自身的值
}
}
}
cout << dp[n][m] << endl;
return 0;
}
希望这次能够正确地回答您的问题,如果还有任何问题,请随时提出。