01背包问题

  • V(i,j)=V(i-1,j)时,说明没有选择第i 个商品,则回到V(i-1,j);
  • V(i,j)=V(i-1,j-w(i))+v(i)时,说明装了第i个商品,该商品是最优解组成的一部分,随后我们得回到装该商品之前,即回到V(i-1,j-w(i));
  • 一直遍历到i=0结束为止,所有解的组成都会找到。
    4 8
    2 3
    3 4
    4 5
    5 6
    
    

 注意此二维矩阵并不代表选取了谁,正真要求选了谁的时候要从最后一个推导

横行代表的是背包当前的容量——不一定是连续操作肯定是一行一行进行操作,但是所表示的价值就不一定了有可能如果图所示,选择了第二件商品和第三件商品。

选中了商品必定是执行的是max后面的部分,而不是继承上一个商品的价值

注意往回推的时候是逆序往回推4->3->2->1知道那间商品有被选中


  • 最优解为V(4,8)=10,而V(4,8)!=V(3,8)却有V(4,8)=V(3,8-w(4))+v(4)=V(3,3)+6=4+6=10,所以第4件商品被选中,并且回到V(3,8-w(4))=V(3,3);
  • 有V(3,3)=V(2,3)=4,所以第3件商品没被选择,回到V(2,3);
  • 而V(2,3)!=V(1,3)却有V(2,3)=V(1,3-w(2))+v(2)=V(1,0)+4=0+4=4,所以第2件商品被选中,并且回到V(1,3-w(2))=V(1,0);
  • 有V(1,0)=V(0,0)=0,所以第1件商品没被选择
    #include<iostream>                
    using namespace std;
    int w[1010],v[1010];
    int dp[1010][1010];
    int main()
    {
    	int n,volume;
    	cin>>n>>volume;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>v[i]>>w[i];
    	 } 
    	 for(int i=1;i<=n;i++)
    	 {
    	 	for(int j=1;j<=volume;j++)                    //当前背包容量j 
    	 	{
    	 		if(j<v[i]) dp[i][j]=dp[i-1][j];
    	 		else dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]); //装了之后容量-v[i],价值增加w[i]; 
    		 }
    	 }
    	 for(int i=0;i<=n;i++)
         {
         		  for(int j=0;j<=volume;j++)
    	  {
    	  	cout << dp[i][j] << ' ';
    	  }
    	  cout<<endl;
    	 }
        cout<<dp[n][volume];
    	return 0;
     } 

    #include<iostream>
    using namespace std;
    #include <algorithm>
     
    int main()
    {
    	int w[5] = { 0 , 2 , 3 , 4 , 5 };			//商品的体积2、3、4、5
    	int v[5] = { 0 , 3 , 4 , 5 , 6 };			//商品的价值3、4、5、6
    	int bagV = 8;					        //背包大小
    	int dp[5][9] = { { 0 } };			        //动态规划表
     
    	for (int i = 1; i <= 4; i++) {
    		for (int j = 1; j <= bagV; j++) {
    			if (j < w[i])
    				dp[i][j] = dp[i - 1][j];
    			else
    				dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
    		}
    	}
     
    	//动态规划表的输出
    	for (int i = 0; i < 5; i++) {
    		for (int j = 0; j < 9; j++) {
    			cout << dp[i][j] << ' ';
    		}
    		cout << endl;
    	}
     
    	return 0;
    }
    

    那么我们继续讨论这个二维矩阵到底代表的是什么:

  • 第一点不重不漏

  • (i,j)集合所表示的是前i个物品,且总体积不超过j的选择方法集合
  • 集合当中每一个方案的最大价值max
  • dp[n][m] 所有物品,总体积不超过最大限制体积的最大值
  • 参考AcWing 2. 01背包问题(闫氏DP分析法) - AcWing
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值