小A点菜
题目分析:
定义f[i][j]为点前i个菜用完j元的方案数;
if(j==a[i]) f[i][j]=f[i-1][j]+1;
如果这个菜的价格刚好可以直接用完j元,那么就有两种方案:
不点这个菜:用点前i-1个菜用完j元的方案
点菜:只点这一个菜直接用完这j元;
那么总方案数就为f[i-1][j]+1
if(j>a[i]) f[i][j]=f[i-1][j]+f[i-1][j-a[i] ];
不点这个菜:为点前i-1个菜用完这j元的方案数
点这个菜:为点前i-1个草用完(j-a[i])的方案数
将两种加起来
if(j<a[i]) f[i][j]=f[i-1][j];
只能不点这个菜:方案数为点前i-1个菜用完j元的方案数
Code:
#include <bits/stdc++.h>
using namespace std;
#define maxn 110
#define maxm 10010
int n,m,a[maxn];
int f[maxn][maxm];
inline void init_() {
freopen("a.txt","r",stdin);
}
inline int read_() {
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
inline void clean_() {
memset(f,0,sizeof(f));
}
inline void readda_() {
clean_();
n=read_();m=read_();
for(int i=1;i<=n;i++) {
a[i]=read_();
}
}
inline void work_() {
for(int i=1;i<=n;i++) {
for(int j=m;j>=1;j--) {
if(j==a[i]) f[i][j]=f[i-1][j]+1;
if(j>a[i]) f[i][j]=f[i-1][j]+f[i-1][j-a[i]];
if(j<a[i]) f[i][j]=f[i-1][j];
}
}
printf("%d",f[n][m]);
}
int main() {
init_();
readda_();
work_();
return 0;
}