描述
给你一个n种面值的货币系统,求组成面值为m的货币有多少种方案。
输入
第一行为n和m。
输出
一行,方案数。
输入样例 1
3 10 //3种面值组成面值为10的方案 1 //面值1 2 //面值2 5 //面值5
输出样例 1
10 //有10种方案
提示
n≤15,m≤3000
动态规划做法:
#include <iostream>
#include <cstring>
int main() {
register unsigned long n, m, ans = 0, * val, * dp;
std::cin >> n >> m;
dp = new unsigned long[m + 1];
val = new unsigned long[n];
for (register unsigned short i = 0; i < n; i++) {
std::cin >> val[i];
}
memset(dp, 0, m * 2 + 2);
dp[0] = 1;
for (register unsigned short i = 1; i <= n; i++) {
for (register unsigned long j = m; j >= val[i - 1]; j--) {
for (register unsigned long k = 1; k <= j / val[i - 1]; k++) {
dp[j] += dp[j - k * val[i - 1]];
}
}
}
std::cout << dp[m];
return 0;
}
深度优先搜索做法:
#include <iostream>
static unsigned short n, m, * val;
static unsigned long ans = 0;
static void dp(register unsigned short crt = 0, register unsigned short start = 0) {
if (crt == m) {
ans++;
return;
}
if (crt > m) {
return;
}
for (register unsigned short i = start; i < n; i++) {
dp(crt + val[i], i);
}
return;
}
int main() {
std::cin >> n >> m;
val = new unsigned short[n];
for (register unsigned short i = 0; i < n; i++) {
std::cin >> val[i];
}
dp();
std::cout << ans;
return 0;
}