问题描述:假定背包的最大容量为W,N件物品,每件物品都有自己的价值和重量,将物品放入背包中使得背包内物品的总价值最大。可以参考链接:
http://www.importnew.com/13072.html
点击打开接
假设背包的最大容量为10,有4件物品,每件物品的重量数组为:[5,4,6,3];相应的每件物品的价值数组为:[10,40,30,50]。
这个问题需要用到动态规划,所以我们首先需要知道这个问题的状态转移方程:假设我们用dp[i][j]表示前i件物品所占据容量j时所获得的最大价值,其中i表示物品的序号,j表示体积。由此,我们可以看出i的取值范围[1-4],j的取值范围为[1-10]。
状态转移方程:dp[i][j] = max{dp[i-1][j],dp[i-1][j-v[i]]+w[i]};其中v[]表示重量数组,w[]表示价值数组。
相应的中文描述为:我们在当前重量下放某一个物品时,有两种可能,放这个物品或者不放这个物品。所以当前dp[i][j]的取值为:若不放此物品,即为前i-1个物品所占据体积的最大价值。若确定放这个物品时,首先我们必须加上这个物品本身的价值,然后我们再计算当前剩余重量(当前重量-占据的重量)可否盛下前i-1个物品。若可以盛的下,就需要再加上前i-1个物品占据剩余的(j-v[i])体积时所获得的最大价值,用dp[i-1][j-v[i]]:
总的来说,这个是个前向取值的过程,他的每一部分解都是看其前面的值。
我们举例来看:
在初始时,假设书包的重量为0,则没有物品放置在书包内,所以第一列全为0,当没有任何物品放置在书包时,书包的重量为0,在任何重量中,其所获得的价值为0,所以第一行全为0。
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
Item1 |
0 |
|
|
|
|
|
|
|
|
|
|
Item2 |
0 |
|
|
|
|
|
|
|
|
|
|
Item3 |
0 |
|
|
|
|
|
|
|
|
|
|
Item4 |
0 |
|
|
|
|
|
|
|
|
|
|
现在,我们放入第一个物品,其重量为5,价值为10。第二行(Item1)表示放入第一个物品,在前4列中的重量<5,所以不能放,到第5列重量为5时,放入第一个物品,所获得的价值为10。在第6列,此时重量为6,还剩余1的重量,此时数据集中所有物品的重量均>1,没有办法再次放入另一个物品,7、8、9、10同理,所以在6、7、8、9、10列中,书包的价值都为10。
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
Item1 |
0 |
0 |
0 |
0 |
0 |
10 |
10 |
10 |
10 |
10 |
10 |
Item2 |
0 |
|
|
|
|
|
|
|
|
|
|
Item3 |
0 |
|
|
|
|
|
|
|
|
|
|
Item4 |
0 |
|
|
|
|
|
|
|
|
|
|
</pre><p></p><p>现在我们假设放入第二个物品,其重量为4,价值为40。第三行表示放入第二个物品,同理1、2、3列为0,在第4列,放入4,价值为40,在第5列,重量为5,不放入4,价值为10,放入4,价值基本上有40,剩余1,放不下前i件物品。所以此时第5列为40,第六列同理,第七列时,不放入4时的价值为10,放入4时,价值基本上有40,剩余3,不够所需的体积。第8列同理,第九列时,不放入4时价值为10,放入4时基本的价值为40,同时剩余5的重量,前1个物品所占5的最大价值为10,两者可以共存,价值为50,此时最大值为50。</p><table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td valign="top"><p> </p></td><td valign="top"><p>0</p></td><td valign="top"><p>1</p></td><td valign="top"><p>2</p></td><td valign="top"><p>3</p></td><td valign="top"><p>4</p></td><td valign="top"><p>5</p></td><td valign="top"><p>6</p></td><td valign="top"><p>7</p></td><td valign="top"><p>8</p></td><td valign="top"><p>9</p></td><td valign="top"><p>10</p></td></tr><tr><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td></tr><tr><td valign="top"><p>Item1</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>10</p></td><td valign="top"><p>10</p></td><td valign="top"><p>10</p></td><td valign="top"><p>10</p></td><td valign="top"><p>10</p></td><td valign="top"><p>10</p></td></tr><tr><td valign="top"><p>Item2</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>50</p></td><td valign="top"><p>50</p></td></tr><tr><td valign="top"><p>Item3</p></td><td valign="top"><p>0</p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td></tr><tr><td valign="top"><p>Item4</p></td><td valign="top"><p>0</p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td></tr></tbody></table><p> </p><p>现在我们放入第三个物品,价值为6,中量为30。第四行表示放入第三个物品。在第四列,时,不放入第三个物品,最大价值为前i-1个物品占据4重量时的最大价值,第五列同理,在第六列时:</p><p>1. 当放入的重量< 第三个物品的重量时,不放入第三个物品,此时的最大价值为40</p><p>2. 当放入的重量 >= 放入第三个物品时,此时的基本价值为30,</p><p>2.1 查看能否与前面的物体共存,具体为,剩余0空间,最大价值我0,总和为30。</p><p>2.2 比较当前重量不放入第三个物品时的最大价值,求其最大值。最终取40.</p><p>第七列同理,第八列同理,第9列同理,第10列时:</p><p>1. 10>6,所以可以放入。此时的基本价值为30.</p><p>1.1 查看共存,剩余4,前2个物品占据4的最大价值为40,可以共存为70。</p><p>1.2 比较求最大值。当不放入第三个物品时的最大价值为50。最大值为70。</p><table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td valign="top"><p> </p></td><td valign="top"><p>0</p></td><td valign="top"><p>1</p></td><td valign="top"><p>2</p></td><td valign="top"><p>3</p></td><td valign="top"><p>4</p></td><td valign="top"><p>5</p></td><td valign="top"><p>6</p></td><td valign="top"><p>7</p></td><td valign="top"><p>8</p></td><td valign="top"><p>9</p></td><td valign="top"><p>10</p></td></tr><tr><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td></tr><tr><td valign="top"><p>Item1</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>10</p></td><td valign="top"><p>10</p></td><td valign="top"><p>10</p></td><td valign="top"><p>10</p></td><td valign="top"><p>10</p></td><td valign="top"><p>10</p></td></tr><tr><td valign="top"><p>Item2</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>50</p></td><td valign="top"><p>50</p></td></tr><tr><td valign="top"><p>Item3</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>0</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>40</p></td><td valign="top"><p>50</p></td><td valign="top"><p>70</p></td></tr><tr><td valign="top"><p>Item4</p></td><td valign="top"><p>0</p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td><td valign="top"><p> </p></td></tr></tbody></table><p>现在放入第4个物品,其重量为3,价值为50,第5行表示加入第四个物品。在1、2、3均小于第4个物品的重量3,不加入,在第4列:</p><p>1. 4>=4,加入4,此时的基本价值为50。</p><p>1.1 查看共存。加入了4时,4-4=0,无法共存。为50。</p><p>1.2 比较不加入。加入前40,加入后50,最大值为50。</p><p>第5列、第6列同理,第7列:</p><p>1. 7>4,可以加入4,此时的基本价值为50.</p><p>1.1 查看共存。剩余7-3=4,此重量的前3个物品、重量为4的价值为40,总共为90</p><p>1.2 比较。加入前40,最大值90.</p><p>第8列:</p><p>1. 8>3,可以加入,此时的基本价值为50</p><p>1.1 查看共存,剩余8-3=5,此重量的前3个物品、重量为5的价值为40,总共为90.</p><p>1.2 比较,加入前40,最大值为90.</p><p>同理第9列和第10列。</p><pre name="code" class="java" style="font-size: 14px; line-height: 21px;">package niuke; import java.util.*; public class BagQuestion { public static void main(String[] args){ Scanner scan = new Scanner(System.in); while(scan.hasNext()){ int total = scan.nextInt(); int number = scan.nextInt(); int[] price = new int[number]; int[] value = new int[number]; for(int i=0;i<number;i++){ price[i] = scan.nextInt(); value[i] = scan.nextInt(); } System.out.println(Arrays.toString(price)); System.out.println(Arrays.toString(value)); int[][] array = new int[number+1][total+1]; // for(int i=0;i<total+1;i++){ // array[0][i]=0; // } // for(int j=0;j<number+1;j++){ // array[j][0]=0; // } for(int i=1;i<number+1;i++){ for(int j=1;j<total+1;j++){ if(price[i-1] <= j){ array[i][j] = Math.max(array[i-1][j], array[i-1][j-price[i-1]]+value[i-1]); }else{ array[i][j] = array[i-1][j]; } } } System.out.println(array[number][total]); } } }