贪心算法是一种在每一步选择中都做出在当前看来最佳的选择,从而希望导致结果是最优的算法。
举个例子,假设我们有一个可以装下重量不超过 W 的背包,并有 n 件物品,第 i 件物品的重量为 w[i],价值为 v[i]。我们希望从中选出若干件物品,装到背包中,使得装入背包中物品的总价值最大。
这个问题就可以使用贪心算法来解决。考虑按照价值与重量的比值来排序,然后从大到小选取物品。如果当前背包容量足够,就将物品装入背包;如果容量不够,就尽量装满。
下面是使用贪心算法来解决背包问题的Java代码:
public static void main(String[] args) {
// 背包物品数量
int n = 5;
// 背包大小
int W = 10;
// 每个物品的体积
int[] w = {2, 2, 6, 5, 4};
// 每个物品的价值
int[] v = {6, 3, 5, 4, 6};
// 每种情况下背包中装入的最大价值
int[][] f = new int[n + 1][W + 1];
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= W; j++) {
if (j < w[i - 1]) {
f[i][j] = f[i - 1][j];
} else {
f[i][j] = Math.max(f[i - 1][j], f[i - 1][j -w[i - 1]] + v[i - 1]);
}
}
}
System.out.println(f[n][W]);
}
在本例中,n=5,代表有5个物品,W=10,代表背包的大小是10。然后,我们有两个数组w和v,分别表示每个物品的体积和价值。
定义二维数组f,用于记录每种情况下背包中装入的最大价值。接着,我们开始使用贪心算法,从前往后枚举每个物品,并计算出它是否应该装入背包中。
首先考虑第一层循环,从1开始遍历所有的物品。然后考虑第二层循环,从0开始遍历所有可能的背包容量。
对于每个物品 i 和容量 j,都有两种选择:选择物品 i,或者不选择物品 i。
当容量 j 大于等于物品 i 的重量时,f[i][j] 可以由两种情况中的最大值得到,即 f[i][j]=max(f[i-1][j],f[i-1][j-w[i-1]]+v[i-1]);
当容量 j 小于物品 i 的重量时,物品 i 不能选择,此时 f[i][j] 的值就等于 f[i-1][j]。最后,输出 f[n][W] 即可得到最大价值。
以此类推,最后得到f[n][W],就是最大价值。
这个算法的时间复杂度是 O(nW),其中 n 是物品数量,W 是背包容量。在计算最优解时,我们需要枚举所有的物品,并且对于每个物品,都需要考虑背包容量的所有可能值。因此,算法的时间复杂度随着物品数量和背包容量的增加而增加。
空间复杂度是 O(nW) 的,因为我们需要一个 nW 大小的二维数组来存储状态。