import java.util.*;
public class Main {
static final int N = 110, M = 10010;
static int[][] f = new int[N][M];
static int[] a = new int[N];
static int n, m;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] str = sc.nextLine().split(" ");
n = Integer.parseInt(str[0]);
m = Integer.parseInt(str[1]);
str = sc.nextLine().split(" ");
for (int i = 1; i <= n; i++) a[i] = Integer.parseInt(str[i - 1]);
//从前i个物品中选,且价值为0的方案数均为1
//什么都不选就是一种选法
for (int i = 0; i < N; i++) f[i][0] = 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
//不选当前物品
f[i][j] = f[i - 1][j];
//选当前物品
//选法为从前i - 1个数中选且价值为j - v的所有选法
//即f[i - 1][j - v]
if (a[i] <= j)
f[i][j] += f[i - 1][j - a[i]];
}
System.out.println(f[n][m]);
}
}
一维优化
f[j]表示前i个数的和恰好为j的方案数的个数
import java.util.*;
public class Main {
static final int N = 110, M = 10010;
static int[] f = new int[M];
static int[] a = new int[N];
static int n, m;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] str = sc.nextLine().split(" ");
n = Integer.parseInt(str[0]);
m = Integer.parseInt(str[1]);
str = sc.nextLine().split(" ");
for (int i = 1; i <= n; i++) a[i] = Integer.parseInt(str[i - 1]);
f[0] = 1;
for (int i = 1; i <= n; i++)
for (int j = m; j >= a[i]; j--) {
f[j] += f[j - a[i]];
}
System.out.println(f[m]);
}
}