动态规划:国王与金矿

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GD_Hacker/article/details/82189004

题目(来源

有一个国家发现了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,动态规划效果不及简单递归。

猜你喜欢

转载自blog.csdn.net/GD_Hacker/article/details/82189004