文章目录
- 01背包
- 1、01背包暴力解法,回溯问题
- 2、动态规划解法
- 3、01背包代码优化
- 完全背包
- 1、完全背包模型
GitHub参考链接
01背包
1、01背包暴力解法,回溯问题
#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、动态规划解法
#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背包代码优化
#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种选择,可以不选、选但不用魔法、选且用魔法。
示例代码:
#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 的情况下的最大价值
#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;
}