货币系统
给定 V V V 种货币(单位:元),每种货币使用的次数不限。
不同种类的货币,面值可能是相同的。
现在,要你用这 V V V 种货币凑出 N N N 元钱,请问共有多少种不同的凑法。
输入格式
第一行包含两个整数 V V V和 N N N。
接下来的若干行,将一共输出 V V V 个整数,每个整数表示一种货币的面值。
输出格式
输出一个整数,表示所求总方案数。
数据范围
1 ≤ V ≤ 25 , 1≤V≤25, 1≤V≤25,
1 ≤ N ≤ 10000 1≤N≤10000 1≤N≤10000
答案保证在 l o n g l o n g long long longlong范围内。
输入样例:
3 10
1 2 5
输出样例:
10
分析: 完全背包问题的求解方案数问题,状态转移方程:
f [ i ] [ j ] = f [ i − 1 ] [ j ] + f [ i − 1 ] [ j − w [ i ] ] + f [ i − 1 ] [ j − 2 ∗ w [ i ] ] + . . . . + f [ i − 1 ] [ j − k ∗ w [ i ] ] f[i][j] = f[i-1][j]+f[i-1][j-w[i]]+f[i-1][j-2*w[i]]+....+f[i-1][j-k*w[i]] f[i][j]=f[i−1][j]+f[i−1][j−w[i]]+f[i−1][j−2∗w[i]]+....+f[i−1][j−k∗w[i]]
表示从前 i i i种货币选,且总价值恰好为 j j j的所有选法的方案数
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=30,M=100010;
long long f[N][M];
int w[N];
int main(){
int v,n;
cin>>v>>n;
for(int i=1;i<=v;i++) cin>>w[i];
f[0][0]=1;
for(int i=1;i<=v;i++){
for(int j=0;j<=n;j++){
for(int k=0;k*w[i]<=j;k++){
f[i][j]+=f[i-1][j-k*w[i]];
}
}
}
cout<<f[v][n]<<endl;
}