题意:你有M元钱,有N道菜,所有菜只能点1次,每道菜价格v[i],问恰好花完所有钱的方案数。
状态:dp[i,j]表示选到第i道菜时,恰好话费j元的方案
转移方程:dp[i,j] = dp[i-1,j] + (j<v[i])? 0 : dp[i-1,j-v[i]].
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e4+5;
ll dp[maxn]; //用滚动数组实现会更方便
ll v[1005];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>v[i];
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=1;i<=n;i++)
for(int j=m;j>=v[i];j--)
dp[j]+=dp[j-v[i]];
cout<<dp[m]<<endl;
return 0;
}