http://poj.org/problem?id=3624
经典的动态规划题目
和买的书上的有一点点差别。
书上开的数组大小是N(商品数量)*M(背包大小)
这样直接提交到POJ,会提示内存不足
经过分析,本次的数据,只和上一行的数据有关系,所以不需要保存以前的历史数据。
int[] RS1=new int[packSize];//存放上一行递归公式的结果
int[] R=new int[packSize];//存放当前行递归公式的结果
完整代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
Sample Input
4 6
1 4
2 6
3 12
2 7
Sample Output
23
http://poj.org/problem?id=3624
*/
public class Main{
public static void main(String args[]) throws IOException {
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
String str=reader.readLine();
int N=Integer.parseInt(str.split(" ")[0]);//商品的数量
int packSize=Integer.parseInt(str.split(" ")[1]);//包的承载量
int[] weight=new int[N];//每个商品的重量
int[] price=new int[N];//每个商品的价值(想要值)
//int[][] R=new int[N][packSize];//存放递归公式的结果
int[] RS1=new int[packSize];//存放上一行递归公式的结果
int[] R=new int[packSize];//存放当前行递归公式的结果
for (int i = 0; i <N ; i++) {
str=reader.readLine();
weight[i]=Integer.parseInt(str.split(" ")[0]);//商品的重量
price[i]=Integer.parseInt(str.split(" ")[1]);//商品的价值(想要值)
}
for (int i = 0; i <N ; i++) {//i是行,代表商品索引
System.arraycopy(R,0,RS1,0,R.length);//R->RS1
for (int j = 0; j <packSize ; j++) {//j是列,代表包的承载量
int pnotIn=0;//当前商品如果不放入的话,价值是多少
if(i-1>=0){//要判断下,防止数组越界
pnotIn=RS1[j];//当前商品不放入的话,价值是上一个商品组合的价值
}else {
if(j-1>=0){
pnotIn=R[j-1];//再差,也得等于上一个的价值
}
}
int pIn=0;//保存当前商品放入的话,价值是多少
if(weight[i]<=(j+1)){//当前商品太重的话,就不存在当前商品放入的情况,所以此处要判断下
pIn=price[i];
if( (i-1>=0) && (j+1-weight[i])>0 ){//要判断下,防止数组越界
pIn=price[i]+RS1[j-weight[i]];//此处的计算简单,但是要用心揣摩,我自己都被绕混了(如果当前商品被放入,价值=( 当前商品的价值+(总容量-当前商品重量)的容量可以存放的最大价值)
}
}
//R[i][j]=Integer.max(pIn,pnotIn);
R[j]=max(pIn,pnotIn);
}
}
reader.close();
System.out.println(R[packSize-1]);
}
public static int max(int i,int j){
if(i>j){
return i;
}else{
return j;
}
}
}