01背包和完全背包

文章目录

GitHub参考链接

01背包

1、01背包暴力解法,回溯问题

c 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e2+5;
int w[N],v[N];
int ans,n,V;
void dfs(int now,int sw,int sv){
	if(now==n+1){
		ans=max(ans,sv);
		return;
	}
	dfs(now+1,sw,sv);
	if(sw+w[now]<=V)dfs(now+1,sw+w[now],sv+v[now]);
}
int main(){
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	cin >> n >> V;
    for (int i = 1; i <= n; ++i) {
        cin >> w[i] >> v[i];
    }
    dfs(1, 0, 0);
    cout<<ans;
	return 0;
}

2、动态规划解法

c 复制代码
#include<bits/stdc++.h> 
using namespace std;
const int N = 1e3+5;
using ll = long long;
ll dp[N][N];// dp[i][j] 表示 第 i 件物品,j 容量,的最大价值 
int n,V;
int main() {
    // dp[i-1][j] //不放物品
	// dp[i-1][j-w[i]]+v[i] //放物品 
    cin>>n>>V;
    for(int i=1;i<=n;i++){
    	ll w,v;cin>>w>>v;
    	for(int j=0;j<=V;j++){
    		if(j>=w)dp[i][j]=max(dp[i-1][j],dp[i-1][j-w]+v);
    		else dp[i][j]=dp[i-1][j];
		}
	}
	cout<<dp[n][V];
    return 0;
}

3、01背包代码优化

c 复制代码
#include<bits/stdc++.h> 
using namespace std;
const int N = 1e3+5;
using ll = long long;
ll dp[N];
int n,V;
int main() {
  	// dp[j] = max(dp[j],dp[j-w]+v); //表示此时物品总重量为 j 的情况下的最大价值 
    cin>>n>>V;
    for(int i=1;i<=n;i++){
    	ll w,v;cin>>w>>v;
    	for(int j=V;j>=w;j--){
    		dp[j]=max(dp[j],dp[j-w]+v);
		}
	}
	cout<<dp[V];
    return 0;
}

例题:

分析:

在背包的基础上加了一个判断,先写背包问题的一般写法,可以过掉40%,在考虑去优化。

对于每个物品有3种选择,可以不选、选但不用魔法、选且用魔法。

示例代码:

c 复制代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 1e4+5;
ll dp[N][2];// 设状态 dp[i][j] 表示物品总重量为 i,且使用了 j 次魔法情况下的最大值 ,j = 0 or 1 
int n,w,v,M,K; 

int main(){
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	cin>>n>>M>>K;
	for(int i=1;i<=n;i++){
		cin>>w>>v;
		// 优化为1维数组来写 
		for(int j=M;j>=0;j--){
			if(j>=w){
				dp[j][0]=max(dp[j][0],dp[j-w][0]+v);
				dp[j][1]=max(dp[j][1],dp[j-w][1]+v);
			}
			if(j>=w+K){
				dp[j][1]=max(dp[j][1],dp[j-w-K][0]+2*v);
			}
		}
	}
	cout<<max(dp[M][0],dp[M][1]); 

	return 0;
}

完全背包

1、完全背包模型

完全背包又叫无穷背包,即每种物品有无数个背包。

有一个体积为V的背包,商店有n个物品,每个物品有一个价值v和体积w,每个物品有无限多个,可以被拿无穷次,问能装下物品的最大价值。

设状态 dp[i]=max(dp[i],dp[i-w]+v) 表示 物品总体积为 i 的情况下的最大价值

c 复制代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll N = 1e4+5;
ll dp[N];
int n,M; 
int main(){
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	cin>>n>>M;
	for(int t=1;t<=n;t++){
		int w,v;cin>>w>>v;
		for(int i=w;i<=M;i++){
			dp[i]=max(dp[i],dp[i-w]+v);
		}
	}
	cout<<dp[M];
	return 0;
}
相关推荐
大数据追光猿16 分钟前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!33 分钟前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉35 分钟前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生35 分钟前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴39 分钟前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing40 分钟前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode
qy发大财40 分钟前
加油站(力扣134)
算法·leetcode·职场和发展
王老师青少年编程40 分钟前
【GESP C++八级考试考点详细解读】
数据结构·c++·算法·gesp·csp·信奥赛
qy发大财41 分钟前
柠檬水找零(力扣860)
算法·leetcode·职场和发展
瓦力的狗腿子44 分钟前
Starlink卫星动力学系统仿真建模番外篇6-地球敏感器
算法·数学建模·simulink