背包九讲

文章目录

  • 背包九讲
    • 01背包问题
    • 完全背包问题
    • 多重背包问题
      • 多重背包问题 I(二进制优化)
      • 多重背包问题 II(单调队列优化)
    • 混合背包问题
    • 二维费用的背包问题
    • 分组背包问题
    • 有依赖的背包问题
    • 背包问题求方案数
    • 背包问题求具体方案

脉络图

01背包问题

题目:

N件物品、容量背包是 V。第 i 件物品的体积是 vi,价值是 wi。每件物品只能使用一次。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N,V≤1000
0<vi,wi≤1000

代码:

#include <bits/stdc++.h>using namespace std;const int N=1010;
int n,m;
int f[N];
int v[N],w[N];int main(){cin>>n>>m;for(int i=1;i<=n;++i) cin>>v[i]>>w[i];for(int i=1;i<=n;++i)for(int j=m;j>=v[i];--j)f[j]=max(f[j],f[j-v[i]]+w[i]);cout<<f[m]<<endl;return 0;
}

完全背包问题

题目:

N件物品、容量背包是 V。第 i 件物品的体积是 vi,价值是 wi。每件物品可以使用多次。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N,V≤1000
0<vi,wi≤1000

代码:

#include <bits/stdc++.h>using namespace std;const int N=1010;
int n,m;
int v[N],w[N];
int f[N];int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;++i) cin>>v[i]>>w[i];for(int i=1;i<=n;++i)for(int j=v[i];j<=m;++j)f[j]=max(f[j],f[j-v[i]]+w[i]);cout<<f[m]<<endl;return 0;
}

多重背包问题

题目:

N件物品、容量背包是 V。第 i 件物品有si个,体积是 vi,价值是 wi。每件物品使用次数不超过si

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,si,用空格隔开,分别表示第 i 件物品的体积、价值和数量。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N,V≤100
0<vi,wi,si≤100

代码:

#include <bits/stdc++.h>using namespace std;const int N=110;
int n,m;
int v[N],w[N],s[N];
int f[N][N];int main(){cin>>n>>m;for(int i=1;i<=n;++i) cin>>v[i]>>w[i]>>s[i];for(int i=1;i<=n;++i)for(int j=0;j<=m;++j)for(int k=0;k<=s[i]&&k*v[i]<=j;++k)f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+w[i]*k);cout<<f[n][m]<<endl;return 0;
}

多重背包问题 I(二进制优化)

题目:

N件物品、容量背包是 V。第 i 件物品有si个,体积是 vi,价值是 wi。每件物品使用次数不超过si

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,si,用空格隔开,分别表示第 i 件物品的体积、价值和数量。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N≤1000
0<V≤2000
0<vi,wi,si≤2000

代码:

#include <bits/stdc++.h>using namespace std;const int N=12010,M=2010;
int n,m;
int v[N],w[N];
int f[N];int main(){cin>>n>>m;int cnt=0;for(int i=1;i<=n;++i){int a,b,s;cin>>a>>b>>s;int k=1;while(s>=k){cnt++;v[cnt]=a*k;w[cnt]=b*k;s-=k;k*=2;}if(s>0){cnt++;v[cnt]=a*s;w[cnt]=b*s;}}n=cnt;for(int i=1;i<=n;++i)for(int j=m;j>=v[i];--j)f[j]=max(f[j],f[j-v[i]]+w[i]);cout<<f[m]<<endl;return 0;
}

多重背包问题 II(单调队列优化)

题目:

N件物品、容量背包是 V。第 i 件物品有si个,体积是 vi,价值是 wi。每件物品使用次数不超过si

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,si,用空格隔开,分别表示第 i 件物品的体积、价值和数量。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N≤1000
0<V≤20000
0<vi,wi,si≤20000

代码:

#include <bits/stdc++.h>using namespace std;const int N=20010;
int n,m;
int f[N],g[N],q[N];int main(){cin>>n>>m;for(int i=0;i<n;++i){int v,w,s;cin>>v>>w>>s;memcpy(g,f,sizeof f);for(int j=0;j<v;++j){int hh=0,tt=-1;for(int k=j;k<=m;k+=v){if(hh<=tt&&q[hh]<k-s*v)hh++;while(hh<=tt&&g[q[tt]]-(q[tt]-j)/v*w<=g[k]-(k-j)/v*w)tt--;q[++tt]=k;f[k]=g[q[hh]]+(k-q[hh])/v*w;}}}cout<<f[m]<<endl;return 0;
}

混合背包问题

N件物品、容量背包是 V。

物品一共有三类:

  • 第一类物品只能用1次(01背包);
  • 第二类物品可以用无限次(完全背包);
  • 第三类物品最多只能用 si次(多重背包);

每种体积是 vi,价值是 wi

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。

接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。

  • si=−1 表示第 i 种物品只能用1次;
  • si=0 表示第 i 种物品可以用无限次;
  • si>0 表示第 i 种物品可以使用 si 次;

输出格式

输出一个整数,表示最大价值。

数据范围

0<N,V≤1000
0<vi,wi≤1000
−1≤si≤1000

代码:

#include <bits/stdc++.h>using namespace std;const int N=1010;
int n,m;
int f[N];int main(){cin>>n>>m;for(int i=0;i<n;++i){int v,w,s;cin>>v>>w>>s;if(!s){for(int j=v;j<=m;++j)f[j]=max(f[j],f[j-v]+w);}else {if(s==-1) s=1;for(int k=1;k<=s;k*=2){for(int j=m;j>=k*v;--j){f[j]=max(f[j],f[j-k*v]+w*k);}s-=k;}if(s){for(int j=m;j>=s*v;--j){f[j]=max(f[j],f[j-s*v]+s*w);}}}}cout<<f[m]<<endl;return 0;
}

二维费用的背包问题

题目:

N件物品、容量背包是 V、背包能承受的最大重量是 M。第 i 件物品的体积是 vi,价值是 wi,重量是 mi。每件物品只能使用一次。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,总重量不超过背包可承受的最大重量,且总价值最大。

输入格式

第一行三个整数,N,V,M,用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。

接下来有 NN 行,每行三个整数 vi,mi,wi,用空格隔开,分别表示第 i 件物品的体积、重量和价值。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N≤1000
0<V,M≤100
0<vi,mi≤100
0<wi≤1000

代码:

#include <bits/stdc++.h>using namespace std;const int N=110;
int n,V,M;
int f[N][N];int main(){cin>>n>>V>>M;for(int i=0;i<n;++i){int v,m,w;cin>>v>>m>>w;for(int j=V;j>=v;--j)for(int k=M;k>=m;--k)f[j][k]=max(f[j][k],f[j-v][k-m]+w);}cout<<f[V][M]<<endl;return 0;
}

分组背包问题

题目:

N件物品、容量背包是 V。每组物品有若干个,同一组内的物品最多只能选一个。每件物品的体积是 vij,价值是 wij,其中 i 是组号,j 是组内编号。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大

输入格式

第一行有两个整数 N,V 用空格隔开,分别表示物品组数和背包容量。

接下来有 N 组数据:

  • 每组数据第一行有一个整数 Si,表示第 i 个物品组的物品数量;
  • 每组数据接下来有 Si 行,每行有两个整数 vij,wij,用空格隔开,分别表示第 i 个物品组的第 j 个物品的体积和价值;

输出格式

输出一个整数,表示最大价值。

数据范围

0<N,V≤100
0<Si≤100
0<vij,wij≤100

代码:

#include <bits/stdc++.h>using namespace std;const int N=110;
int n,m;
int v[N][N],w[N][N],s[N];
int f[N];int main(){cin>>n>>m;for(int i=1;i<=n;++i){cin>>s[i];for(int j=0;j<s[i];++j)cin>>v[i][j]>>w[i][j];}for(int i=1;i<=n;++i)for(int j=m;j>=0;--j)for(int k=0;k<s[i];++k)if(v[i][k]<=j)f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);cout<<f[m]<<endl;return 0;
}

有依赖的背包问题

有 N 个物品和一个容量是 V 的背包。

物品之间具有依赖关系,且依赖关系组成一棵树的形状。如果选择一个物品,则必须选择它的父节点。

如下图所示:

如果选择物品5,则必须选择物品1和2。这是因为2是5的父节点,1是2的父节点。

每件物品的编号是 i,体积是 vi,价值是 wi,依赖的父节点编号是 pi。物品的下标范围是 1…N。

求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式

第一行有两个整数 N,V,用空格隔开,分别表示物品个数和背包容量。

接下来有 N 行数据,每行数据表示一个物品。
第 ii 行有三个整数 vi,wi,pi,用空格隔开,分别表示物品的体积、价值和依赖的物品编号。
如果 pi=−1,表示根节点。 数据保证所有物品构成一棵树。

输出格式

输出一个整数,表示最大价值。

数据范围

1≤N,V≤100
1≤vi,wi≤100

父节点编号范围:

  • 内部结点:1≤pi≤N;
  • 根节点 pi=−1;

代码:

#include <bits/stdc++.h>using namespace std;const int N=110;
int n,m;
int v[N],w[N];
int h[N],e[N],ne[N],idx;
int f[N][N];void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}void dfs(int u){for(int i=h[u];i!=-1;i=ne[i]){int son=e[i];dfs(e[i]);for(int j=m-v[u];j>=0;--j){for(int k=0;k<=j;++k){f[u][j]=max(f[u][j],f[u][j-k]+f[son][k]);}}}for(int i=m;i>=v[u];--i)f[u][i]=f[u][i-v[u]]+w[u];for(int i=0;i<v[u];++i)f[u][i]=0;
}int main(){cin>>n>>m;memset(h,-1,sizeof h);int root;for(int i=1;i<=n;++i){int p;cin>>v[i]>>w[i]>>p;if(p==-1) root=i;else add(p,i);}dfs(root);cout<<f[root][m]<<endl;return 0;
}

背包问题求方案数

N件物品、容量背包是 V。第 i 件物品的体积是 vi,价值是 wi。每件物品只能使用一次。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输出最优选法的方案数。注意答案可能很大,请输出答案模 109+7 的结果。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式

输出一个整数,表示方案数模 109+7 的结果。

数据范围

0<N,V≤1000
0<vi,wi≤1000

代码:

#include <bits/stdc++.h>using namespace std;const int N=1010,mod=1e9+7;
int n,m;
int f[N],g[N];int main(){cin>>n>>m;memset(f,-0x3f,sizeof f);f[0]=0;g[0]=1;for(int i=0;i<n;++i){int v,w;cin>>v>>w;for(int j=m;j>=v;--j){int maxv=max(f[j],f[j-v]+w);int cnt=0;if(maxv==f[j]) cnt+=g[j];if(maxv==f[j-v]+w) cnt+=g[j-v];g[j]=cnt%mod;f[j]=maxv;}}int res=0;for(int i=0;i<=m;++i) res=max(res,f[i]);int cnt=0;for(int i=0;i<=m;++i)if(res==f[i])cnt=(cnt+g[i])%mod;cout<<cnt<<endl;return 0;
}

背包问题求具体方案

N件物品、容量背包是 V。第 i 件物品的体积是 vi,价值是 wi。每件物品只能使用一次。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输出字典序最小的方案

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式

输出一行,包含若干个用空格隔开的整数,表示最优解中所选物品的编号序列,且该编号序列的字典序最小。

物品编号范围是 1…N。

数据范围

0<N,V≤1000
0<vi,wi≤1000

代码:

#include <bits/stdc++.h>using namespace std;const int N=1010;
int n,m;
int v[N],w[N];
int f[N][N];int main(){cin>>n>>m;for(int i=1;i<=n;++i) cin>>v[i]>>w[i];for(int i=n;i>0;--i)for(int j=0;j<=m;++j){f[i][j]=f[i+1][j];if(j>=v[i])f[i][j]=max(f[i][j],f[i+1][j-v[i]]+w[i]);}int j=m;for(int i=1;i<=n;++i)if(j>=v[i]&&f[i][j]==f[i+1][j-v[i]]+w[i]){cout<<i<<" ";j-=v[i];}return 0;
}

题目来源

背包九讲(例题+代码)相关推荐

  1. 算法--背包九讲(详细讲解+代码)

    背包九讲 目录  第一讲 01背包问题  第二讲 完全背包问题  第三讲 多重背包问题  第四讲 混合三种背包问题  第五讲 二维费用的背包问题  第六讲 分组的背包问题  第七讲 有依赖的背包问题  ...

  2. 【算法】动态规划+“背包九讲”原理超详细讲解+常见dp问题(9种)总结

    目录 一.动态规划(DP) 二.背包九讲 (1)完全背包 P1616 疯狂的采药(完全背包) (2)01背包 滚动数组 一维数组 P1048 采药(01背包) 01背包表格图示 (3)多重背包 整数拆 ...

  3. 完全背包问题python_令人头疼的背包九讲(2)完全背包问题

    重磅干货,第一时间送达 背包问题是一个经典的动态规划模型.它既简单形象容易理解,又在某种程度上能够揭示动态规划的本质,故不少教材都把它作为动态规划部分的第一道例题. 题目 完全背包问题 题目要求 有n ...

  4. dalao的背包九讲

    背包九讲 目录  第一讲 01背包问题  第二讲 完全背包问题  第三讲 多重背包问题  第四讲 混合三种背包问题  第五讲 二维费用的背包问题  第六讲 分组的背包问题  第七讲 有依赖的背包问题  ...

  5. 【转】《背包九讲》--崔添翼大神

    背包九讲 目录 第一讲 01背包问题 第二讲 完全背包问题 第三讲 多重背包问题 第四讲 混合三种背包问题 第五讲 二维费用的背包问题 第六讲 分组的背包问题 第七讲 有依赖的背包问题 第八讲 泛化物 ...

  6. 转载——背包九讲(原文链接已不可考)

    浙大崔添翼对背包问题的讲解,观点很高也很深刻,特此转载. 背包九讲 目录  第一讲 01背包问题  第二讲 完全背包问题  第三讲 多重背包问题  第四讲 混合三种背包问题  第五讲 二维费用的背包问 ...

  7. dd大牛的背包九讲-背包问题汇总

    背包九讲 目录  第一讲 01背包问题  第二讲 完全背包问题  第三讲 多重背包问题  第四讲 混合三种背包问题  第五讲 二维费用的背包问题  第六讲 分组的背包问题  第七讲 有依赖的背包问题  ...

  8. 背包九讲 (蒟蒻版)之01背包

    hello,你们的loony上线啦.你们知道吗?我今天早上起来一看手机,600多人在CSDN上访问过我,当时我心情都要炸了(补充:高兴炸了),因为,这毕竟只是本蒟蒻的梦想嘛~ 好了不嘚瑟啦! 今天就来 ...

  9. dp背包九讲(待补充,暂时前两讲)

    文章目录 背包九讲 一.01背包 二维dp 优化为一维 二.完全背包 二维dp 优化为一维 三.多重背包 数据范围很小时,变成01背包暴力 当数据范围较大时,利用二进制优化 二进制优化还不够用时,利用 ...

  10. 第二讲 完全背包问题(对背包九讲的学习)

    学习自:背包九讲 题目 有N种物品和一个容量为V的背包,每种物品都有无限件可用.第i种物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. ...

最新文章

  1. python读取、写入、移动、复制文件(夹)以及其他关于文件(夹)的操作
  2. 干货|为什么Kafka不支持读写分离
  3. cad新手必练300图_[CAD]平面练习图,CAD新手练技术练速度的好去处
  4. 关于使用AsyncTaskLoader的使用
  5. Visual Studio Code 11 月 Python 扩展更新
  6. ssh协议是osi_你见过这份864页神仙级的TCP/IP协议吗?,太香了!
  7. slam无人车在web端地图编辑
  8. 好的网站链接或文章链接(一)
  9. linux df -h显示空间信息不正确
  10. hud 4415 Assassin’s Creed
  11. 纯真IP/ZXinc_IPv6数据库镜像及MySQL脚本更新同步更新 for Python 3.x
  12. 2016 server win 假死_Windows 7假死的几个常见情况以及解决方法
  13. 【BackEnd】SpringBoot整合MybatisPlus实现登录注册功能(适合初学者)
  14. 李宏毅2020机器学习作业3-CNN:食物图片分类
  15. hive 中创建表的三种方式
  16. 老罗(www.luocong.com)
  17. 如何在word中粘贴美观工整的代码段(planetB/notepad++)
  18. 文件上传与下载SmartUpload
  19. 运算符:is与==的区别
  20. 农夫过河(基于C语言)

热门文章

  1. 挑战程序设计竞赛——Ants(POJ No.1852)
  2. php学生宿舍管理系统免费,PHP学生宿舍管理系统
  3. Windows10永久关闭自动更新,禁止windows10自动更新方法!
  4. 汇编语言中sbb是什么意思_汇编语言的所有指令
  5. matlab里用simulink仿真教程,Matlab-Simulink仿真教程课件.ppt
  6. 国外卫星地图mapbox的基本操作
  7. EasyX画动态时钟
  8. EXCEL 趋势图生成的公式应用说明
  9. PLC编程技术的发展及应用
  10. 最大功率点跟踪测试软件,最大功率点追踪