【01背包问题】从后往前滚动数组
【要求凑整数】边界值:[0][0]=1,0枚硬币凑0面值、算一种方案;[0][j]=0
【统计方案数】转移方程:a+b

#include<iostream>
#include<climits>
using namespace std;


//0-1背包的凑整问题统计方案数
int main(){
    
    int n;
    int volume[21];
    int dp[41];
    volume[0] = 0;
    
    while(cin>>n){
        for(int i=1;i<=n;i++){
            cin>>volume[i];
        }
        
        dp[0] = 1;
        for(int i=1;i<41;i++) dp[i]=0;
        
        for(int i=1;i<=n;i++){
            for(int j=40;j>=volume[i];j--){
                dp[j] = dp[j]+dp[j-volume[i]];
            }
            
            /*
            for(int j=0;j<=40;j++){
                cout<<dp[j]<<',';
            }
            cout<<endl;
            */
        }
        cout<<dp[40]<<endl;
        
    }
    
    
    return 0;
}