动态规划-0/1背包问题(含全部代码)

题目:

假设你是一个小偷,有一个可放总重量为m(m<1000)的背包。现有n(n<32)件物品。
      总量分别为W1,W2,...,Wn。并且,物品具有价值,分别为V1,V2,...,Vn。m、n、Wi(1=       现要求你尝试挑选几件物品,使这些物品重量之和为m。求能装入的最大总价值。
输入格式:
第一行为两个正整数m和n
接下来n行分别为n对整数,分别表示该物品的重量和价值。      
Example:
Input:
4 3
1 1500
3 2000
4 3000
Output:
3500  

【分析】

         假设物品1为吉他(G表示)、物品2为音响(S表示)、物品3为笔记本电脑(C表示)
          dp[i][j]表示前i件物品,在重量为j时的最大价值。很明显,出口即为第0行(没有物品)和第0列(没有背包空间)。

          状态转移方程
          dp[i-1][j],W[i]>j(装不下,当没看见物品i吧)
          max(dp[i-1][j],dp[i-1][j-W[i]]+V[i]) ,W[i]<=j(装的下,聪明的你选择装与不装的最佳方案)

手算模拟:

物品(重量、价值)   0 1 2 3 4
无物品 0 0 0 0 0 0
G(1、1500) 1 0 G(1500) G(1500) G(1500) G(1500)
S(3、2000) 2 0 G(1500) G(1500) S(2000) G+S(3500)
C(4、3000) 3 0 G(1500) G(1500) S(2000) G+S(3500)

        假设你眼神不太好,仅看到吉他。我们先填前1件物品行,即吉他行。很明显,吉他占1磅,1、2、3、4列均是吉他,价值1500。

        这时,你又看到了音响,偷不偷呢?我们看前两件物品,前两列很明显,装不下音响(W[i]>j),没办法,偷不走。那么,是不是和没看见音响一样啊(dp[i][j]=dp[i-1][j]),即音响行1、2列复制吉他行。第三列可以装下音响(W[i]<=j),聪明的你经过比较发现音响价值更高【max(dp[i-1][j],dp[i-1][j-W[i]]+V[i])】,于是装了音响。那么,第四列呢?这就相当于你有两个背包,一个能放重量为3的,一个能放重量为1的(子问题加和),当前最优解为2000,那么多出来的能放重量为1的小背包的最优解是吉他。所以,重量为4时当然就加和在一起喽。

        最后,你发现了桌子上的笔记本电脑,那么装不装呢?装的话(价值3000),重量就减少了(dp[i-1][j-W[i]]+V[i])。不装的话,价值(dp[i-1][j],即3500)会比笔记本电脑多吗?答案是肯定的。所以,就当没看见笔记本电脑吧。

代码:

/*
Project:
Date:    2019/01/10
Author:  Frank Yu
题目:假设你是一个小偷,有一个可放总重量为m(m<1000)的背包。现有n(n<32)件物品。
      总量分别为W1,W2,...,Wn。并且,物品具有价值,分别为V1,V2,...,Vn。m、n、Wi(1=j(装不下,当没看见物品i吧) 
        max(dp[i-1][j],dp[i-1][j-W[i]]+V[i]) ,W[i]<=j(装的下,聪明的你选择装与不装的最佳方案)
		   
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define maxm 1000
#define maxn 32
using namespace std;
int W[maxn],V[maxn];
//打印表 
void display(int dp[maxn][maxm],int m,int n)
{
		 for(int i=0;i<=n;i++)
	 {
	  for(int j=0;j<=m;j++)
	 	cout<j) dp[i][j]=dp[i-1][j];//第i件物品太重,放弃	
	 	  else
		   {
		   	int choose = dp[i-1][j-W[i]]+V[i];//选了,价值增加 
		    int nochoose = dp[i-1][j];
			dp[i][j] =max(choose,nochoose);
		   } 	 	  
	 	}
	 }
     //display(dp,m,n);	 	
	 cout<

结果截图:

动态规划-0/1背包问题(含全部代码)_第1张图片 运行截图

此程序可以优化:动态规划-0/1背包优化(含全部代码)

0/1背包考虑了物品的重量和价值,但是每种物品只有一件,显然不符合现实。作为一名有眼力的小偷,如果手表即轻又贵,当然不要拿又重又相对便宜的笔记本电脑喽。

那么,考虑物品数量时又会如何呢?作有志气的小偷,请往下看。

请看完全背包:动态规划-完全背包(含全部代码)

更多数据结构与算法实现:数据结构(严蔚敏版)与算法的实现(含全部代码)

有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。

你可能感兴趣的:(动态规划,算法,数据结构,常见算法与数据结构实现)