回顾复习之背包DP
\(\small{(本文统一将c[i]视作cost,w[i]视作worth,下面的代码用这两个变量表示费用和价值)}\)
\(\Large\textbf{1. 01背包}\)
- \(\large\textbf{描述:}\)
有n个物品,每个物品只有一件,第i个物品体积为vi,价格为ci。现在有一个体积为V的背包,请你从n件物品里选出若干件放进背包里,使得背包里的物品价值最大。 - \(\large\textbf{思路:}\)
01背包的特点是:每种物品只有一件,可以选择放或不放。
我们可以根据此特点进行动态规划(DP),设f[i][j]表示前i件物品放入一个容量为j的背包中可以获得的最大价值,则易得状态转移方程为
dp[i][j]=max(dp[i-1][j],dp[i-1][j-c[i]]+w[i])
(详解:在“将前i个物品放入容量为j的背包中”的这个子问题中,由题意,我们只有\(\textbf{放}\)或\(\textbf{不放}\)两种选择,那么就转化为一个只与前i-1个物品有关的问题。如果不放第i件物品,那么就是“前i-1件物品放入容量为j的背包中”,最大价值为f[i-1][j];如果放第i件物品,那么就是“前i-1件物品放入剩下的容量为j-c[i]的背包中”,最大价值为f[i-1][j-c[i]]+w[i])
由此可得01背包的\(\textbf{最原始}\)代码
$\large\textbf{code}$
#include<bits/stdc++.h>
using namespace std;
#define N 1010
#define Elaina 0
int n,m,V,c[N],w[N],dp[N][N],ans=0;
void bag(){
for(int i=1;i<=n;i++){
for(int j=1;j<=V;j++){
dp[i][j]=dp[i-1][j];
if(j>=c[i]){
dp[i][j]=max(dp[i-1][j],dp[i-1][j-c[i]]+w[i]);
}
}
}
}
int main(){
cin>>n>>V;
for(int i=1;i<=n;i++){
cin>>c[i]>>w[i];
}
bag();
cout<<dp[n][V];
return Elaina;
}
以上代码的时间和空间的复杂度均为O(V*N),其中时间已经不能进一步优化了,但是空间可以
\(\textbf{滚动数组优化code}\)
code
#include<bits/stdc++.h>
using namespace std;
#define N 1010
#define Elaina 0
int n,m,V,c[N],w[N],ans=0;
int dp[2][N];//滚动数组优化 只开2行数组
void bag(){
for(int i=1;i<=n;i++){
for(int j=1;j<=V;j++){
dp[i&1][j]=dp[(i-1)&1][j];
if(j>=c[i]){
dp[i&1][j]=max(dp[i&1][j],dp[(i-1)&1][j-c[i]]+w[i]);
}
}
}
}
int main(){
cin>>n>>V;
for(int i=1;i<=n;i++){
cin>>c[i]>>w[i];
}
bag();
cout<<dp[n&1][V];
return Elaina;
}
\(\textbf{一维优化code}\)
code
#include<bits/stdc++.h>
using namespace std;
#define N 1010
#define Elaina 0
int n,m,V,c[N],w[N],ans;
int dp[N];//一维数组优化
void bag(){
for(int i=1;i<=n;i++){
for(int j=V;j>=c[i];j--){
dp[j]=max(dp[j],dp[j-c[i]]+w[i]);
}
}
}
int main(){
cin>>n>>V;
for(int i=1;i<=n;i++){
cin>>c[i]>>w[i];
}
bag();
cout<<dp[V];
return Elaina;
}
\(\Large\textbf{2. 完全背包}\)
- \(\large\textbf{描述:}\)
设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。 - \(\large\textbf{思路:}\)
完全背包的特点是:每种物品有无数件,可以选择放若干件或不放。
设k为取的物品的数量,依据01背包思路,易得状态转移方程为
dp[i][j]=max(dp[i-1][j],dp[i-1][j-k*c[i]]+k*w[i])
完整代码为
$\large\textbf{code}$
#include<bits/stdc++.h>
using namespace std;
#define N 10100
#define Elaina 0
int n,m,V,c[N],w[N],dp[N][N],ans=0;
void bag(){
for(int i=1;i<=n;i++){
for(int j=1;j<=V;j++){
for(int k=0;k*c[i]<=j;k++){
dp[i][j]=max(dp[i-1][j],dp[i-1][j-k*c[i]]+k*w[i]);
}
}
}
}
int main(){
cin>>V>>n;
for(int i=1;i<=n;i++){
cin>>c[i]>>w[i];
}
bag();
cout<<dp[n][V];
return Elaina;
}
\(\textbf{一维优化code}\)
code
#include<bits/stdc++.h>
using namespace std;
#define N 10100
#define Elaina 0
int n,m,V,c[N],w[N],dp[N],ans=0;
void bag(){
for(int i=1;i<=n;i++){
for(int j=c[i];j<=V;j++){
dp[j]=max(dp[j],dp[j-c[i]]+w[i]);
}
}
}
int main(){
cin>>V>>n;
for(int i=1;i<=n;i++){
cin>>c[i]>>w[i];
}
bag();
cout<<dp[V];
return Elaina;
}
\(\Large\textbf{3. 多重背包}\)
- \(\large\textbf{描述:}\)
有N种物品和一个容量为V的背包。第i ii种物品最多有p[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 - \(\large\textbf{思路:}\)
这题目和完全背包问题很类似。基本的方程只需将完全背包问题的方程略微一改即可,因为对于第i种物品有p[i]+1种策略:取0件,取1件……取p[i]件。令dp[i][j]表示前i种物品恰放入一个容量为j的背包的最大价值,则有状态转移方程:
dp[i][j]=max(dp[i][j],dp[i-1][j-k*c[i]]+k*w[i])
$\large\textbf{code}$
#include<bits/stdc++.h>
using namespace std;
#define N 10100
#define Elaina 0
int n,m,V,c[N],w[N],dp[N][N],s[N];
void bag(){
for(int i=1;i<=n;i++){
for(int j=1;j<=V;j++){
for(int k=0;k<=s[i]&&k*c[i]<=j;k++){
dp[i][j]=max(dp[i][j],dp[i-1][j-k*c[i]]+k*w[i]);
}
}
}
}
int main(){
cin>>n>>V;
for(int i=1;i<=n;i++){
cin>>c[i]>>w[i]>>s[i];
}
bag();
cout<<dp[n][V];
return Elaina;
}
\(\textbf{一维优化code}\)
code
#include<bits/stdc++.h>
using namespace std;
#define N 1010
#define Elaina 0
int n,m,V,c[N],w[N],dp[N],s[N];
void bag(){
for(int i=1;i<=n;i++){
for(int j=V;j>=0;j--){
for(int k=0;k<=s[i]&&k*c[i]<=j;k++){
dp[j]=max(dp[j],dp[j-k*c[i]]+k*w[i]);
}
}
}
}
int main(){
cin>>n>>V;
for(int i=1;i<=n;i++){
cin>>c[i]>>w[i]>>s[i];
}
bag();
cout<<dp[V];
return Elaina;
}
\(\Large\textbf{4. 混合背包}\)
- \(\large\textbf{描述:}\)
一个旅行者有一个最多能用V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn。有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包)。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
(就是把前01背包、完全背包、多重背包搓起来 搓吧搓吧就出来了(^_−)☆)
直接请出代码君
code
#include<bits/stdc++.h>
using namespace std;
#define N 10100
#define inf 0x3f3f3f3f
#define Elaina 0
int idx=0,n,V,c[N],w[N],dp[N],s[N],ans=inf;
void bag(){
for (int i=1; i<=n; i++){
if(s[i]==1){
for(int j=V;j>=c[i];j--){
dp[j]=max(dp[j],dp[j-c[i]]+w[i]);
}
}
else if(s[i]==0){
for(int j=c[i];j<=V;j++){
dp[j]=max(dp[j],dp[j-c[i]]+w[i]);
}
}else{
for(int j=V;j>=0;j--){
for(int k=0;k<=s[i]&&k*c[i]<=j;k++){
dp[j]=max(dp[j],dp[j-k*c[i]]+k*w[i]);
}
}
}
}
}
int main(){
cin>>V>>n;
for(int i=1;i<=n;i++){
cin>>c[i]>>w[i]>>s[i];
}
bag();
cout<<dp[V];
return Elaina;
}
\(\Large\textbf{5. 分组背包}\)
- \(\large\textbf{描述:}\)
一个旅行者有一个最多能用V公斤的背包,现在有n件物品,它们的重量分别是W1,W2,...,Wn,它们的价值分别为C1,C2,...,Cn。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大 - \(\large\textbf{死路:}\)
这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。也就是说设dp[k][j]表示前k组物品花费费用j能取得的最大价值,则有:
dp[k][j]=max(dp[k][j],dp[k-1][j-c[i]]+w[i]
\(\textbf{一维优化code}\)
code
#include<bits/stdc++.h>
using namespace std;
#define N 10100
#define ll long long
#define inf 0x3f3f3f3f
#define Elaina 0
int n,t,V,T,c[N],w[N],dp[N],g[N][N];
void bag(){
for (int i=1; i<=T; i++){
for(int j=V;j>=0;j--){
for(int k=1;k<=g[i][0];k++){
int x=g[i][k];
if(j>=c[x]){
dp[j]=max(dp[j],dp[j-c[x]]+w[x]);
}
}
}
}
}
int main(){
cin>>V>>n>>T;
for(int i=1;i<=n;i++){
cin>>c[i]>>w[i]>>t;
g[t][++g[t][0]]=i;
}
bag();
cout<<dp[V];
return Elaina;
}
回顾复习之背包DP的更多相关文章
- 复习1背包dp
背包问题是对于一个有限制的容器,一般计算可以装的物品的价值最值或数量.通常每个物品都有两个属性空间和价值,有时还有数量或别的限制条件,这个因体而异. 背包大概分成3部分,下面会细述这最经典的3种题型 ...
- 算法复习——背包dp
1.01背包 二维递推式子: 代码: ;i<=n;i++) ;x--) ][x-w[i]]+c[i],f[i-][x]); ][x]; printf("%d",f[n][m] ...
- hdu 2844 混合背包【背包dp】
http://acm.hdu.edu.cn/showproblem.php?pid=2844 题意:有n种纸币面额(a1,a2,...an),每种面额对应有(c1,c2,...cn)张.问这些钱能拼成 ...
- 背包dp整理
01背包 动态规划是一种高效的算法.在数学和计算机科学中,是一种将复杂问题的分成多个简单的小问题思想 ---- 分而治之.因此我们使用动态规划的时候,原问题必须是重叠的子问题.运用动态规划设计的算法比 ...
- hdu 5534 Partial Tree 背包DP
Partial Tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...
- HDU 5501 The Highest Mark 背包dp
The Highest Mark Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
- Codeforces Codeforces Round #319 (Div. 2) B. Modulo Sum 背包dp
B. Modulo Sum Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/577/problem/ ...
- noj [1479] How many (01背包||DP||DFS)
http://ac.nbutoj.com/Problem/view.xhtml?id=1479 [1479] How many 时间限制: 1000 ms 内存限制: 65535 K 问题描述 The ...
- HDU 1011 树形背包(DP) Starship Troopers
题目链接: HDU 1011 树形背包(DP) Starship Troopers 题意: 地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...
- BZOJ 1004: [HNOI2008]Cards( 置换群 + burnside引理 + 背包dp + 乘法逆元 )
题意保证了是一个置换群. 根据burnside引理, 答案为Σc(f) / (M+1). c(f)表示置换f的不动点数, 而题目限制了颜色的数量, 所以还得满足题目, 用背包dp来计算.dp(x,i, ...
随机推荐
- python · ssh · SQL | python 连接远程 SQL 数据库
python 连接本地 SQL 的 教程存档. 如果要连接远程的 SQL 数据库,需要先开一个 ssh 连接,在 ssh 连接里写 pymysql 的 connect 代码. 代码如下: ''' pi ...
- [转帖]etcd raft模块解析
https://www.cnblogs.com/luohaixian/p/16641100.html 1. Raft简介 raft是一个管理复制式日志的共识算法,它是通过复制日志的方式来保持状态机里的 ...
- [转帖]88. sys_kwr
88. sys_kwr ¶ 88.1. 插件sys_kwr简介 ¶ 插件sys_kwr是KingbaseES 的一个扩展插件.主要功能是通过周期性自动记录性能统计相关的快照,分析出KingbaseES ...
- 周末拾遗 xsos 的学习与使用
周末拾遗 xsos 的学习与使用 摘要 周末陪儿子上跆拳道课. 自己一个人傻乎乎的开着笔记本想着学习点东西. 上午看到了一个sosreport的工具. 本来想学习一下. 发现xsos 应该是更好的一个 ...
- [转帖]网络传输性能netperf测试方法和下载
简介 Netperf是一种网络性能的测试工具,主要针对基于TCP或UDP的传输.Netperf根据应用的不同,可以进行不同模式的网络性能测试,即批量数据传输(bulk data transfer)模式 ...
- [转帖]java -d 参数(系统属性) 和 环境变量
https://www.cnblogs.com/limeiyang/p/16565920.html 1. -d 参数说明 通过 java -h 查看可知: 注意:-D= : set a system ...
- SQLSERVER 数据库根据LCK_M_S对应的waitsorce 查看被锁的表信息的简单方法
公司一个开发大牛召冠总搞过一个 DMSQLMONITOR 工具 能够识别Oracle以及SQLSERVER 数据库的锁和事务等问题, 非常好用 今天环境出现了不可用的情况, 所以这边着急进行一下问题分 ...
- 2024了,我不想再用AOP收集业务操作日志了 | 京东云技术团队
0.背景 在近期的项目中,系统涉及到针对系统的业务操作日志统计功能,由于本系统位于业务链路的中心环节,负责接收上游系统的数据,并将基于用户操作产生的数据传递至下游系统,鉴于业务链路的复杂性和操作场景的 ...
- css中使用蒙层会带来哪些问题。
css中使用蒙层会带来哪些问题. 1==> 如果蒙层设置的背景颜色或者透明度. 蒙层里面的子集元素将会受到影响: 此时子集元素可能不能注册点击的事件. 因为蒙层将它覆盖住了 2==> 此时 ...
- 【代码分享】使用 terraform, 在 ZeroSSL 上申请托管在 cloudflare 上的域名对应的证书
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 接上一篇:<使用 terraform, 在 Let' ...