题目描述
给你一个n种面值的货币系统,求组成面值为m的货币有多少种方案。样例:设n=3,m=10,要求输入和输出的格式如下:
输入
第一行两个整数n,m(m<=5000)
以下n行,每行一个整数,第i+1行为第i种货币的面值
输出
一个整数,为方案数
输入样例
3 10
1
2
5
输出样例
10
思路
用动态规划的思想去做,先画一个二维表,再得出状态方程,属于完全背包问题,dp[i][j]表示用前i种货币能表示j面值货币的方案数,则对第i种货币也有选和不选的策略,而总的方案数为二者之和,因此可得状态转移方程:
dp[i][j]=dp[i-1][j]+dp[i][v-a[i]]
#include <iostream>
using namespace std;
const int Max = 5e3+5;
long long dp[Max][Max];
int a[Max];
int main()
{
int n,m;
cin>>n>>m;
for(int i = 1;i <= n; ++i)
{
cin>>a[i];
}
for(int i = 1;i <= n; ++i)
{
for(int j = 1;j <= m; ++j)
{
if(j < a[i])
dp[i][j] = dp[i-1][j]; //当面值小于第i个货币的面值时,方案数与i-1的时候相同
else if(j == a[i])
dp[i][j] = dp[i-1][j]+1;//当面值等于第i个货币的面值时,方案书比第i-1时候的方案数加1;
else
dp[i][j] = dp[i-1][j]+dp[i][j-a[i]];
}
}
cout<<dp[n][m]<<endl;
return 0;
}