m
思路:当没有思路的时候可以考虑用暴力搜索的方式来做。当第n种花,摆放了m盆时候的方案是多少?就可以从第一种花,放了0盆开始搜索。跳出条件时,当放的数量达到m时跳出,则把这种方案记录为一种。当大于m时,返回0跳出。花的种类用超了时,也返回0并跳出。爆搜效率会过不去,可以考虑用记忆搜索,把以前计算过的值保存下来,这样用到的时候直接返回。记忆优化的可以转动态规划,动态规划不一定可以转记忆化搜索
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class p1077 {
static int maxn=105, mod = 1000007;
static int n,m;
static int a[]=new int[maxn];
static int [][]rmb=new int[maxn][maxn];
static int [][]f=new int[maxn][maxn];
public static void main(String[] args)throws Exception {
System.setIn(new FileInputStream("E:\\data\\p1077.txt"));
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st=new StringTokenizer(br.readLine());
n=Integer.parseInt(st.nextToken());
m=Integer.parseInt(st.nextToken());
st=new StringTokenizer(br.readLine());
for(int i=1;i<=n;i++){
a[i]=Integer.parseInt(st.nextToken());
}
// int result=dfs(1,0);
System.out.println(solve2());
}
//第n种花放了k盆以后的方案数
static int dfs(int x,int k){
if(k > m) return 0;
if(k == m) return 1;
if(x == n+1) return 0;
if(rmb[x][k]!=0) return rmb[x][k]; //搜过了就返回
int ans = 0;
for(int i=0; i<=a[x]; i++) ans = (ans + dfs(x+1, k+i))%mod;
rmb[x][k] = ans; //记录当前状态的结果
return ans;
}
static int solve2(){
f[0][0] = 1;
for(int i=1; i<=n; i++)
for(int j=0; j<=m; j++)
for(int k=0; k<=Math.min(j, a[i]); k++)
f[i][j] = (f[i][j] + f[i-1][j-k])%mod;
return f[n][m];
}
}