动态规划(转载)
http://www.cnblogs.com/sdjl/articles/1274312.html
import java.util.Scanner ;
public class Max{
private int[] peopleNeed ; //每座金矿需要的人数 ;
private int[] gold ; //每座金矿能够挖出来的金子数 ;
private int[][] maxGold ; //maxGold[i][j]保存了i个人挖前j个金矿能够得到的最大金子数,等于-1表示未知
public Max(int peopleTotal, int n){
peopleNeed = new int[n] ;
gold = new int[n] ;
maxGold = new int[peopleTotal][n] ;//等于-1表示未知,对应动态规划中的“备忘录”;
for(int i=0;i<peopleTotal;i++) {
for(int j=0;j<n;j++){
maxGold[i][j] = -1 ;
}
}
}
public int getMaxGold(int people, int mineNum){//获得在仅有people个人和mineNum个金矿时能够得到的最大金子数,注意“前多少个”也是从0开始编号;
if(maxGold[people][mineNum]!=-1){ //首先查看备忘录是否有记录,若有,直接返回即可;
return maxGold[people][mineNum] ;
}else{
int retMaxGold ; //若无,进行计算 ;
if(mineNum==0){ //检查边界情况 ;
if(people>=peopleNeed[mineNum]){
retMaxGold = gold[mineNum] ;
}else{
retMaxGold = 0 ;
}
}else{
if(people>=peopleNeed[mineNum]){ //如果给出的人能够开采这座金矿 ;
int a = getMaxGold(people-peopleNeed[mineNum],mineNum-1) + gold[mineNum] ;
int b = getMaxGold(people,mineNum-1) ;
retMaxGold = Math.max(a, b) ;
}else{ //如果给出的人不能开采这座金矿 ;
retMaxGold = getMaxGold(people,mineNum-1) ;
}
}
maxGold[people][mineNum] = retMaxGold ; //记录在备忘录中
return retMaxGold ;
}
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in) ;
int people = sc.nextInt() ; //输入总人数 ;
int n = sc.nextInt() ; //输入金矿数 ;
Max m = new Max(people,n) ;
for(int i=0;i<n;i++){
m.peopleNeed[i] = sc.nextInt() ;
m.gold[i] = sc.nextInt() ;
}
System.out.println(m.getMaxGold(people-1,n-1)) ; //输出给定 people 个人和 n 个金矿所能获得的最大金子数,再次提醒编号从0开始,所以最后一个金矿编号为 n-1 ;
}
}
浙公网安备 33010602011771号