给定 V种货币(单位:元),每种货币使用的次数不限。
不同种类的货币,面值可能是相同的。
现在,要你用这 V种货币凑出 N 元钱,请问共有多少种不同的凑法。
输入格式
第一行包含两个整数 V 和 N。
接下来的若干行,将一共输入 V 个整数,每个整数表示一种货币的面值。
输出格式
输出一个整数,表示所求总方案数。
数据范围
1≤V≤25,
1≤N≤10000
答案保证在long long
范围内。
输入样例:
3 10
1 2 5
输出样例:
10
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;// 定义长整型别名,方便后续使用
typedef long long LL;// 定义常量 N 和 M,分别表示物品数量上限和背包容量上限
const int N = 30, M = 10010;// n 表示物品数量,m 表示背包容量
int n, m;
// v 数组用于存储每个物品的体积
int v[N];
// f 数组用于存储状态,f[i][j] 表示前 i 个物品装满容量为 j 的背包的方案数
LL f[N][M];int main()
{// 从标准输入读取物品数量 n 和背包容量 mscanf("%d%d", &n, &m);// 循环读取每个物品的体积for (int i = 1; i <= n; i ++ ) scanf("%d", &v[i]);// 初始化状态,当没有物品且背包容量为 0 时,方案数为 1f[0][0] = 1;// 动态规划过程,枚举每个物品for (int i = 1; i <= n; i ++ )// 枚举背包的每个容量for (int j = 0; j <= m; j ++ ){// 不选择第 i 个物品的方案数f[i][j] = f[i - 1][j];// 如果当前背包容量 j 大于等于第 i 个物品的体积 v[i]if (j >= v[i]) // 选择第 i 个物品的方案数,累加到 f[i][j] 中f[i][j] += f[i][j - v[i]];}// 输出前 n 个物品装满容量为 m 的背包的方案数printf("%lld\n", f[n][m]);return 0;
}