很久很久以前,有一位国王有5座金矿,每座金矿的黄金储量不同,需要参加挖掘的工人人数也不同。例如有的金矿储量是500Kg黄金,需要5个人来挖掘。有的金矿储量是200Kg。需要三个人来挖掘。
如果参与挖矿的工人总数是10.每座金矿要么全挖,要么不挖。不能派出一半人挖取一半的金矿。要求用程序求出,要想得到尽可能多的黄金,应该选择挖取哪几座金矿?
以下为可选条件:
共10人 200Kg/3人 300Kg/4人 350Kg/3人 400Kg/5人 500Kg/5人
/**
* @Author: subd
* @Date: 2019/9/3 8:07
* 金矿问题
*/
public class BestGoldMining {
public static void main(String[] args) {
int w = 10;
int[] p = {5, 5, 3, 4, 3};
int[] g = {400, 500, 200, 300, 350};
Long time = System.currentTimeMillis();
System.out.println("V1最优收益: " + getBestGoldMining(w, g.length, p, g));
System.out.println("V1花费时间: " + (System.currentTimeMillis() - time));
time = System.currentTimeMillis() ;
System.out.println("V2最优收益: " + getBestGoldMiningV2(w, g.length, p, g));
System.out.println("V2花费时间: " + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
System.out.println("V3最优收益: " + getBestGoldMiningV3(w, p, g));
System.out.println("V3花费时间: " + (System.currentTimeMillis() - time));
}
/**
* 获得金矿最优收益
*
* @param w 工人数量
* @param n 可选金矿数量
* @param p 金矿开采所需的工人数量
* @param g 金矿储量
* @return
*/
public static int getBestGoldMining(int w, int n, int[] p, int[] g) {
if (w == 0 || n == 0) {
return 0;
}
if (w < p[n - 1]) {
return getBestGoldMining(w, n - 1, p, g);
}
return Math.max(getBestGoldMining(w, n - 1, p, g), getBestGoldMining(w - p[n - 1], n - 1, p, g) + g[n - 1]);
}
/**
* 获得金矿最优收益
*
* @param w 工人数量
* @param n 可选金矿数量
* @param p 金矿开采所需的工人数量
* @param g 金矿储量
* @return
*/
public static int getBestGoldMiningV2(int w, int n, int[] p, int[] g) {
//创建表格
int[][] resultTable = new int[g.length + 1][w + 1];
//填充表格
for (int i = 1; i <= g.length; i++) {
for (int j = 0; j <= w; j++) {
if (j < p[i - 1]) {
resultTable[i][j] = resultTable[i - 1][j];
} else {
resultTable[i][j] = Math.max(resultTable[i - 1][j], resultTable[i - 1][j - p[i - 1]] + g[i - 1]);
}
}
}
//返回最后1个格子的值
return resultTable[g.length][w];
}
/**
* 获得金矿最优收益
*
* @param w 工人数量
* @param p 金矿开采所需的工人数量
* @param g 金矿储量
* @return
*/
public static int getBestGoldMiningV3(int w, int[] p, int[] g) {
//创建当前结果
int[] results = new int[w + 1];
//填充一维数组
for (int i = 1; i <= g.length; i++) {
for (int j = w; j >= 1; j--) {
if (j >= p[i - 1]) {
results[j] = Math.max(results[j], results[j - p[i - 1]] + g[i - 1]);
}
}
}
//返回最后1个格子的值
return results[w];
}
}
2965

被折叠的 条评论
为什么被折叠?



