定义 fif_i 为凑出 ii 元的纸币方式数,因此答案是 fwf_w

需要初始化 f0=1f_0=1,因为凑出 00 元只有一种方式,就是不给钱。

凑出 ii 元的组方式是 ii 分别减去每种纸币面额的方式数的和,即 j=1nfiaj\sum_{j=1}^n f_{i-a_j}。状态转移方程如下。

fi=j=1nfiajf_i=\sum_{j=1}^n f_{i-a_j}

注意取模。注意数组溢出。

#include<iostream>
using namespace std;
int n,w,a[1005],f[10005];
const int mod=1e9+7;
int main(){
    cin>>n>>w;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    f[0]=1;
    for(int i=1;i<=w;i++){
        for(int j=1;j<=n;j++){
            if(i-a[j]>=0){
                f[i]=(f[i]+f[i-a[j]])%mod;
            }
        }
    }
    cout<<(f[w]%mod)<<endl;
    return 0;
}