题目描述:
金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早金明就开始做预算,但是他想买的东西太多了,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一个重要度,分为5等:用整数1~5表示,第5等最重要。他还从因特网上查到了每件物品的价格(都是整数元)。他希望在不超过N元(可以等于N元)的前提下,使每件物品的价格与重要度的乘积的总和最大。
样例输入
1000 5
800 2
400 5
300 5
400 3
200 2
样例输出
3900
思路介绍:
在写这个题之前我希望你们先点一下链接看一下这个关于采药的问题,这个问题和这个题的意思大致是和上面一样的,
就拿上面的例子来看吧
1000 5(限制条件)
800 2
400 5
300 5
400 3
200 2
我们首先建立一个二维数组array[6][2];如下所示:
0 | 0 | 0行 |
---|---|---|
800 | 2*800 | 1行 |
400 | 5*400 | 2行 |
300 | 5*300 | 3行 |
400 | 3*400 | 4行 |
200 | 2 *200 | 5行 |
这是事先要完成的,然后我们可以再建立一个二维数组bb[ 5+1][1000+1 ]
如果bb[i][j]代表的意思是不超过j元钱,前i件物品可以取得的最大值
那么很明显bb[i][0]=0,bb[0][j]=0
假设Wj代表的是第j件物品的价值,Vj表示第j件物品的钱数,那么如果Wj>j的时候bb[i][j]=bb[i-1][j],因为时候第j件物品的价值已经超过了可容纳的价值了,所以等于bb[i-1][j],
如果Wj<j时候有两种结果,要么就是第j件物品放进去了,此时的bb[i][j]=bb[i-1][j-Vj]+Wj
如果不放进去的话,此时bb[i][j]=bb[i-1][j],而这种情况就是取最大值了,大致的思路就是这样的,最后只要输出bb[5][1000]就可以得到结果了。
代码如下:
public class Main2 {
public static void main(String[] args) {
Scanner m=new Scanner(System.in);
int a=m.nextInt();
int b=m.nextInt();
int array[][]=new int[b+1][2];
for(int i=1;i<array.length;i++)
for(int j=0;j<array[i].length;j++)
array[i][j]=m.nextInt();
for(int i=1;i<array.length;i++)
array[i][1]=array[i][1]*array[i][0];
int sm[][]=new int[b+1][a+1];
for(int i=0;i<a;i++)
sm[0][i]=0;
for(int k=0;k<b;k++)
sm[k][0]=0;
for(int i=1;i<sm.length;i++)
for(int j=1;j<sm[i].length;j++)
if(array[i][0]>j)
sm[i][j]=sm[i-1][j];
else
sm[i][j]=max(sm[i-1][j],sm[i-1][j-array[i][0]]+array[i][1]);
System.out.println(sm[b][a]);
}
public static int max(int i, int j) {
// TODO Auto-generated method stub
int max=i>j?i:j;
return max;
}
}