引用:

题解:

这是一道比较含蓄的背包问题(完全背包)。

我们将总钱数(目标钱数)的大小看作背包的容量V

每张钱的费用即为其面值w[i]。 那么在价值上我们可能就要动动脑子想一想了。

无疑价值绝对是方案数啦 (≧▽≦)/啦啦啦。

但是转移方程是?

我们把情况分为两类(类似01背包),即选或不选。

当不选的时候,方案数应该是之前的几种钱凑成当前钱数的方案数,即f[j]=f[j];

当选的时候,方案数会增加,一部分是原来方案f[j],另一部分为前几种钱凑成剩余钱数的方案数(因为除此之

外的钱都要用当前面值钞票凑成)故转移方程为f[j]=f[j]+f[j-w[i]].

两个合二为一即f[j]=f[j-w[i]]+f[j],这就是我们要的转移方程

当我们开始枚举时,将j=w[1]代入我们就不难发现,边界条件应该为f[0]=1;

友情提示:这是完全背包,枚举时一定要用顺序枚举!

#include <cstdio>
using namespace std;
int v,n,an[30];
long long vn[10005];
int max(int a,int b){return a>b?a:b;}
int main(){
    scanf("%d%d",&v,&n);
    for(int i=1;i<=v;i++)scanf("%d",&an[i]);
    vn[0]=1;
    for(int i=1;i<=v;i++)
        for(int j=an[i];j<=n;j++)
            vn[j]=vn[j]+vn[j-an[i]];
    printf("%lld",vn[n]);
    return 0;
}