经典算法问题——01背包

Posted 哈拉泽空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典算法问题——01背包相关的知识,希望对你有一定的参考价值。

b站讲解视频

https://www.bilibili.com/video/BV1ob411C7gg?from=search&seid=9137415201994217470

首先第一点:明确dp[i][j]表达的含义:存放的是一共i个物品,所用容量为j时,最大的价值

递推关系式:
d p [ i ] [ j ] = d p [ i − 1 ] [ j ] if volume[i]>j m a x ( d p [ i − 1 ] [ j ] ,    d p [ i − 1 ] [ j − v o l u m e [ i ] ] + v a l u e [ i ] ) if volume[i]<=j dp[i][j]= \\begincases dp[i-1][j] & \\textif volume[i]>j\\\\ max(dp[i-1][j],\\ \\ dp[i-1][j-volume[i]]+value[i]) & \\textif volume[i]<=j\\\\ \\endcases dp[i][j]=dp[i1][j]max(dp[i1][j],  dp[i1][jvolume[i]]+value[i])if volume[i]>jif volume[i]<=j

解释:

  1. i f    v o l u m e [ i ] > j if \\ \\ volume[i]>j if  volume[i]>j

    意思是当前背包容量为j,第i个物品需要容量为volume[i]

    那需要容量都比剩余容量大了,当然没法放进去啦!

  2. i f    v o l u m e [ i ] < = j if \\ \\ volume[i]<=j if  volume[i]<=j

    意思是需要容量小于剩余容量,当然可以放进去,但放不放还需要做一下取舍:

    所以取放或不放的最大值
    m a x ( d p [ i − 1 ] [ j ] ,    d p [ i − 1 ] [ j − v o l u m e [ i ] ] + v a l u e [ i ] ) max(dp[i-1][j],\\ \\ dp[i-1][j-volume[i]]+value[i]) max(dp[i1][j],  dp[i1][jvolume[i]]+value[i])

code for HDU 2602

#include<cstring>
#include<iostream>
using namespace std;

const int maxn=1005;

int N,V;
int weight[maxn],value[maxn],res[maxn][maxn];

int max(int a,int b)
	return a>b?a:b;


void package()
	memset(res,0,sizeof(res));
	for(int i=1;i<=N;i++)
		for(int j=0;j<=V;j++)//不必纠结这里是从0开始还是从1开始,从0开始是考虑了可能会有物品体积为0,但是价值不为0的情况(也就是这类物品随便放,反正不会站价值,这种情况要是从1开始,那岂不是错过了这些免费的物品?)根据具体题目而定
			if(weight[i]>j) res[i][j]=res[i-1][j];
			else
				res[i][j]=max(res[i-1][j],res[i-1][j-weight[i]]+value[i]);
			
		
	


int main()
	int t;
	cin>>t;
	while(t--)
		cin>>N>>V;
		for(int i=1;i<=N;i++) cin>>value[i];
		for(int i=1;i<=N;i++) cin>>weight[i];
		package();
		cout<<res[N][V]<<endl;
	 
	
	return 0;
 

练习题

https://vjudge.net/problem/HDU-2602

以上是关于经典算法问题——01背包的主要内容,如果未能解决你的问题,请参考以下文章

动态规划算法-07背包问题进阶

算法期末备考-第5练-动态规划

动态规划算法-07背包问题进阶

P1049 装箱问题(01背包)

经典动态规划之01背包

C语言 背包问题 递归算法