$$\color{Red}{货币系统:完全背包求方案数(二维——》一维)}$$
我做的所有的题解
包括基础提高以及一些零散刷的各种各样的题
证明
板子题,可以看我之前的题解。
完全背包问题:三种语言+原版和滚动数组优化
java 二维朴素
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static int N = 3010, n, m;
static long[][] f = new long[20][N];
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
String[] s1 = br.readLine().split(" ");
n = Integer.parseInt(s1[0]);
m = Integer.parseInt(s1[1]);
f[0][0] = 1;
for (int i = 1; i <= n; i++) {
int v = Integer.parseInt(br.readLine());
for (int j = 0; j <= m; j++)
for (int k = 0; k * v <= j; k++)
f[i][j] += f[i - 1][j - k * v];
}
System.out.println(f[n][m]);
}
}
java 二维优化
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static int N = 3010, n, m;
static long[][] f = new long[20][N];
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
String[] s1 = br.readLine().split(" ");
n = Integer.parseInt(s1[0]);
m = Integer.parseInt(s1[1]);
f[0][0] = 1;
for (int i = 1; i <= n; i++) {
int v = Integer.parseInt(br.readLine());
for (int j = 0; j <= m; j++) {
f[i][j] = f[i-1][j];
if(j >= v)
f[i][j] += f[i][j - v];
}
}
System.out.println(f[n][m]);
}
}
java 一维优化
能减少如此多的条件,关键就是在于
f[i][j] = f[i-1][j] + f[i][j - v]
我们for循环可以采取直接选择v开始,就是因为计算f[j] += f[j - v]
此时调用的f[j]其实就是上一个i-1状态下的f[i-1][j]
因此省却了先赋值上一层,然后再加错位项的情况
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static int N = 3010, n, m;
static long []f = new long[N];
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
String [] str = br.readLine().split(" ");
n = Integer.parseInt(str[0]);
m = Integer.parseInt(str[1]);
f[0] = 1;
for (int i = 1; i <= n; i++) {
int v = Integer.parseInt(br.readLine());
for (int j = v; j <= m; j++) {
f[j] += f[j - v];
}
}
System.out.println(f[m]);
}
}