题目(来源)
有一个国家发现了5座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人数也不同。参与挖矿工人的总数是10人。每座金矿要么全挖,要么不挖,不能派出一半人挖取一半金矿。要求用程序求解出,要想得到尽可能多的黄金,应该选择挖取哪几座金矿?
递归实现
public static void main(String[] args) {
int[] p = new int[]{3, 4, 3, 5, 5};
int[] g = new int[]{200, 300, 350, 400, 500};
int gold = new Main().maxGold(5, 10, p, g);
System.out.println(gold);
}
public int maxGold(int n, int w, int[] p, int[] g) {
if (n == 1) {
return w < p[n - 1] ? 0 : g[n - 1];
}
if (w < p[n - 1]) {
return maxGold(n - 1, w, p, g);
}
return Math.max(maxGold(n - 1, w, p, g), maxGold(n - 1, w - p[n - 1], p, g) + g[n - 1]);
}
动态规划
/** * @param n 金矿数量 * @param w 工人数量 * @param p 第n个金矿需要工人数量 * @param g 第n个金矿金子数量 * @return void * @Description 采用动态规划获取w个工人从n个金矿中能挖到的最大金子数量 **/
public void getMaxGold(int n, int w, int[] p, int[] g) {
int[] preResult = new int[w];
int[] result = new int[w];
for (int i = 0; i < w; i++) {
if (i+1 < p[0]) {
preResult[i] = 0;
} else {
preResult[i] = g[0];
}
}
for (int i = 1; i < n; i++) {
for (int j = 0; j < w; j++) {
if (j+1 < p[i] ) {
result[j] = preResult[j];
}else if(j+1 == p[i]){
result[j] = Math.max(preResult[j], preResult[j-p[i]+1] + g[i]);
} else {
result[j] = Math.max(preResult[j], preResult[j - p[i]] + g[i]);
}
}
show(result);
preResult = result.clone();
}
}
public void show(int[] array){
for(int i:array){
System.out.print(i+" ");
}
System.out.println();
}
两种方法的选择应根据实际情况,如果例子中金矿数不变,而工人数变为10000,动态规划效果不及简单递归。