国王挖矿
国王挖矿和01背包问题很像,都是两个维度的问题分析取最大值。
这种问题都是找到最优子结构,写出状态转移方程 基本就解出来了
例如10个人挖5个矿的价值 = Max(10个人去挖4个矿的价值,挖第5个矿的价值+10个人扣掉第5个矿的人去挖前4个矿的价值)
动态规划将问题规模逐渐变小,利用数组对之前的运算进行存储避免因为递归而产生的重复计算。
解题步骤:
1.减小问题规模
2.找出状态转移方程
3.边界
实现代码
/**
* 动态规划
* 挖矿 10个工人挖 5个矿 矿的黄金产量和需要人数分别为(500,5) (200,3) (300,4) (350,3) (400,5)
* 如何挖 达到最大值
*/
public static void digGold(){
int[] gold = {500,200,300,350,400};
int[] persons = {5,3,4,3,5};
int[][] values = new int[6][11];
for(int i=1; i<6;i++){ //矿
for(int j=1;j<11;j++){ //人数
if(j >= persons[i-1]){ //如果当前人数还能挖矿
// 10个人挖5个矿的状态转移方程是values[5,10] = Max(values[4,10],values[4][10-person[4]+gold[4]])
if(values[i-1][j] > values[i-1][j-persons[i-1]] + gold[i-1]){
//10人挖4个矿
values[i][j] = values[i-1][j];
}
else { //10人挖5个矿
values[i][j] = values[i-1][j-persons[i-1]] + gold[i-1];
}
}else{ //当前人数不能挖矿了
values[i][j] = values[i-1][j];
}
}
}
int j = 10;
for(int i = 5;i>0;i--){
if(values[i][j] != values[i-1][j]){
System.out.println("挖了" + i +"矿,用了" + persons[i-1]+"人");
j -= persons[i-1];
}
}
System.out.println("总价值:"+values[5][10]);
}