首页 > 其他分享 >背包问题

背包问题

时间:2023-01-08 18:11:26浏览次数:23  
标签:背包 容量 int 问题 DP dp SIZE

背包问题

0-1背包

动态转移方程

\(dp_{i,j}\)代表在背包容量只有\(i\)的时候,拿前\(j\)件物体能拿最大的价值。

\[ \begin{cases} dp_{i,j}=dp_{i,j-1}(背包容量不够时,W_i>j)\\ dp_{i,j}=\max(dp_{i,j-1},dp_{i-W_j,j-1}+V_i)(背包容量够时,W_i \le j) \end{cases}\]

初值

\(dp_{i,0}=0,dp_{0,j=0}\),因为只有\(0\)件物体只能拿价值总和为\(0\)的物体而背包容量只有\(0\)也只能拿价值总和为\(0\)的物体。

终值

\(dp_{w,n}\)
因为\(dp_{i,j}\)代表在背包容量只有\(i\)的时候,拿前\(j\)件物体能拿最大的价值。
而要求在背包容量只有\(w\)的时候,拿前\(n\)件物体(全部物体)能拿最大的价值。

code

code1

#include<bits/stdc++.h>
using namespace std;
const int SIZE = 205;
int main() {
	int W[SIZE], C[SIZE], M, N; //W容量,C价值,M背包容量,N物品数量
	int DP[SIZE][SIZE];         //i容量 j物品
	cin >> M >> N;
	for (int i = 1; i <= N; i++) cin >> W[i] >> C[i];
	for (int i = 0; i <= M; i++)DP[i][0] = 0;
	for (int i = 0; i <= N; i++)DP[0][i] = 0;
	for (int i = 1; i <= N; i++)//枚举物品
		for (int j = 0; j <= M; j++) //枚举容量
			if (W[i] > j) DP[j][i] = DP[j][i - 1];
			else          DP[j][i] = max(DP[j - W[i]][i - 1] + C[i], DP[j][i - 1]);
	cout << DP[M][N];
	return 0;
}

code2

#include<bits/stdc++.h>
using namespace std;
const int SIZE = 205;
int main() {
	int W[SIZE], C[SIZE], M, N; 			//W容量,C价值,M背包容量,N物品数量
	int DP[SIZE] = {};       				//i容量 j物品
	cin >> M >> N;
	for (int i = 1; i <= N; i++) cin >> W[i] >> C[i];
	for (int i = 1; i <= N; i++)			//枚举物品
		for (int j = M; j >= 0; j--)	    //枚举容量 
			if (W[i] > j) DP[j] = DP[j];
			else          DP[j] = max(DP[j - W[i]] + C[i], DP[j]);
	cout << DP[M];
	return 0;
}
//10:14 注意:要逆向 

标签:背包,容量,int,问题,DP,dp,SIZE
From: https://www.cnblogs.com/kimi-learn/p/17035025.html

相关文章