动态规划-01背包(模板)、完全背包(模板)、多重背包1(模板)、多重背包2(模板)、背包与魔法、砝码称重

发布时间:2026/9/25 10:03:46

动态规划-01背包(模板)、完全背包(模板)、多重背包1(模板)、多重背包2(模板)、背包与魔法、砝码称重
问题描述有 NN 件物品和一个体积为 MM 的背包。第 ii 个物品的体积为 vivi​价值为 wiwi​。每件物品只能使用一次。请问可以通过什么样的方式选择物品使得物品总体积不超过 MM 的情况下总价值最大输出这个最大价值即可。输入格式第一行输入两个正整数 N,MN,M。(1≤N,M≤1000)(1≤N,M≤1000)接下来 NN 行每行输入两个整数 vi,wivi​,wi​。(0≤vi,wi≤1000)(0≤vi​,wi​≤1000)输出格式输出一个整数表示符合题目要求的最大价值。样例输入4 5 1 2 2 4 3 4 4 5样例输出8说明你可以选择第二个物品和第三个物品。import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.*; public class Main { static int N1010; static int v[]new int[N]; static int w[]new int[N]; static int f[]new int[N]; static int n; static BufferedReader br new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bwnew BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { StringTokenizer stnew StringTokenizer(br.readLine()); nInteger.parseInt(st.nextToken()); int m Integer.parseInt(st.nextToken()); for (int i 1; i n; i) { stnew StringTokenizer(br.readLine()); v[i]Integer.parseInt(st.nextToken()); w[i]Integer.parseInt(st.nextToken()); } //定义f[i][j]为只考虑前i件 背包体积不超过j的最大价值 // for (int i 1; i n; i) { // for (int j 1; j m; j) { // if(jv[i])f[i][j]Math.max(f[i-1][j], f[i-1][j-v[i]]w[i]); // else f[i][j]f[i-1][j]; // } // } // 空间上可以用两行优化 可以利用行的奇偶性来进行区分 // for (int i 1; i n; i) { // for (int j 1; j m; j) { // if(jv[i])f[i1][j]Math.max(f[(i-1)1][j], f[(i-1)1][j-v[i]]w[i]); // else f[i1][j]f[(i-1)1][j]; // } // } // bw.write(f[n1][m]); //一维数组优化 for (int i 1; i n; i) { for (int j m; j 1; j--) {//注意要从大到小 if(jv[i])f[j]Math.max(f[j], f[j-v[i]]w[i]); } } bw.write(f[m]); br.close(); bw.flush(); bw.close(); } }完全背包模板问题描述有 NN 件物品和一个体积为 MM 的背包。第 ii 个物品的体积为 vivi​价值为 wiwi​。每件物品可以使用无限次。请问可以通过什么样的方式选择物品使得物品总体积不超过 MM 的情况下总价值最大输出这个最大价值即可。输入格式第一行输入两个正整数 N,MN,M。(1≤N,M≤1000)(1≤N,M≤1000)接下来 NN 行每行输入两个整数 vi,wivi​,wi​。(0≤vi,wi≤1000)(0≤vi​,wi​≤1000)输出格式输出一个整数表示符合题目要求的最大价值。样例输入4 5 1 2 2 4 3 4 4 5样例输出10说明你可以选择 11 个第一个物品和 22 个第二个物品。import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.*; public class Main { static int N1010; static int v[]new int[N]; static int w[]new int[N]; static int f[]new int[N]; static int n; static BufferedReader br new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bwnew BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { StringTokenizer stnew StringTokenizer(br.readLine()); nInteger.parseInt(st.nextToken()); int m Integer.parseInt(st.nextToken()); for (int i 1; i n; i) { stnew StringTokenizer(br.readLine()); v[i]Integer.parseInt(st.nextToken()); w[i]Integer.parseInt(st.nextToken()); } //定义f[i][j]为只考虑前i件 背包体积不超过j的最大价值 // f[i , j ] max( f[i-1,j] , f[i-1,j-v]w , f[i-1,j-2*v]2*w , f[i-1,j-3*v]3*w , .....) // f[i , j-v] max( f[i-1,j-v] , f[i-1,j-2*v] w , f[i-1,j-3*v]2*w , .....) // 由上两式可得出如下递推关系 // f[i][j]max(f[i,j-v]w , f[i-1][j]) // for (int i 1; i n; i) { // for (int j 1; j m; j) { // if(jv[i])f[i][j]Math.max(f[i-1][j], f[i][j-v[i]]w[i]); // else f[i][j]f[i-1][j]; // } // } // 空间上用两行优化 可以利用行的奇偶性来进行区分 // for (int i 1; i n; i) { // for (int j 1; j m; j) { // if(jv[i])f[i1][j]Math.max(f[(i-1)1][j], f[(i)1][j-v[i]]w[i]); // else f[i1][j]f[(i-1)1][j]; // } // } // bw.write(f[n1][m]); //一维数组优化 for (int i 1; i n; i) { for (int j 1; j m; j) {//注意要从小到大 if(jv[i])f[j]Math.max(f[j], f[j-v[i]]w[i]); } } bw.write(f[m]); br.close(); bw.flush(); bw.close(); } }多重背包1模板问题描述有 NN 件物品和一个体积为 MM 的背包。第 ii 个物品的体积为 vivi​价值为 wiwi​。每件物品只能使用 cici​ 次。请问可以通过什么样的方式选择物品使得物品总体积不超过 MM 的情况下总价值最大输出这个最大价值即可。输入格式第一行输入两个正整数 N,MN,M。(1≤N,M≤100)(1≤N,M≤100)接下来 NN 行每行输入三个整数 vi,wi,civi​,wi​,ci​。(0≤vi,wi,ci≤100)(0≤vi​,wi​,ci​≤100)输出格式输出一个整数表示符合题目要求的最大价值。样例输入4 5 1 2 3 2 4 1 3 4 3 4 5 2样例输出10import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.*; public class Main { static int N1010; static int v[]new int[N]; static int w[]new int[N]; static int c[]new int[N]; static int f[][]new int[N][N]; static int n; static BufferedReader br new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bwnew BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { StringTokenizer stnew StringTokenizer(br.readLine()); nInteger.parseInt(st.nextToken()); int m Integer.parseInt(st.nextToken()); for (int i 1; i n; i) { stnew StringTokenizer(br.readLine()); v[i]Integer.parseInt(st.nextToken()); w[i]Integer.parseInt(st.nextToken()); c[i]Integer.parseInt(st.nextToken()); } //定义f(i,j)为 只考虑前i件物品 背包体积不超过j 的最大价值 for (int i 1; i n ;i) { for (int j 1; j m; j) { f[i][j]f[i-1][j]; for (int k 1; k c[i]; k) { if(jk*v[i])f[i][j]Math.max(f[i][j],f[i-1][j-k*v[i]]k*w[i]); } } } bw.write(f[n][m]); br.close(); bw.flush(); bw.close(); } }多重背包2模板问题描述有 NN件物品和一个体积为 MM的背包。第 ii个物品的体积为 vivi​价值为 wiwi​。每件物品只能使用 cici​ 次。请问可以通过什么样的方式选择物品使得物品总体积不超过 MM的情况下总价值最大输出这个最大价值即可。由于评测机过快本题数据于 2024-12-16 加强N,MN,M上调至 2×1032×103以杜绝多重背包1的做法通过输入格式第一行输入两个正整数 N,MN,M。(1≤N,M≤2000)(1≤N,M≤2000)接下来 NN行每行输入三个整数 vi,wi,civi​,wi​,ci​。(1≤vi,wi,ci≤2000)(1≤vi​,wi​,ci​≤2000)输出格式输出一个整数表示符合题目要求的最大价值。样例输入4 5 1 2 3 2 4 1 3 4 3 4 5 2样例输出10import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.*; public class Main { static int N22010; // 要把 2000 完全拆开比如拆成 1, 2, 4, ..., 1024, 剩余最多需要 11 个分组。 // 所以总的分组数上限 2000 × 11 22000。 static int v[]new int[N]; static int w[]new int[N]; static int c[]new int[N]; static int f[]new int[N]; static int n; static BufferedReader br new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bwnew BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { StringTokenizer stnew StringTokenizer(br.readLine()); nInteger.parseInt(st.nextToken()); int m Integer.parseInt(st.nextToken()); int p1; for (int i 1; i n; i) { stnew StringTokenizer(br.readLine()); int vvInteger.parseInt(st.nextToken()); int wwInteger.parseInt(st.nextToken()); int ccInteger.parseInt(st.nextToken()); int tccc; //比如13 可以写成 148 可以分成3个物品 然后0/1背包去选 int k1; //比如 13 可以拆出 1 2 4 8不能要因为要了没那么多物品13-76 6 //可以证明 1 2 4 可以凑出 0-7 的任何数 如果再加上6 就可以凑出 6-13的数 while(cck){ v[p]k*vv; w[p]k*ww; p; cc-k; k1; } if(cc0){ v[p]cc*vv; w[p]cc*ww; p; } } //定义f(i,j)为 只考虑前i件物品 背包体积不超过j 的最大价值 for (int i 1; i p ;i) { for (int j m; j 1; j--) { if(jv[i])f[j]Math.max(f[j],f[j-v[i]]w[i]); } } bw.write(f[m]); br.close(); bw.flush(); bw.close(); } }背包与魔法题目描述小蓝面前有 N 件物品其中第 i 件重量是 Wi价值是 Vi。她还有一个背包最大承重是 M。小蓝想知道在背包称重范围内她最多能装总价值多少的物品特别值得一提的是小蓝可以使用一个魔法将一件物品的重量增加 K同时价值翻倍。(当然小蓝也可以不使用魔法输入格式第一行包含 3 个整数 N、M 和 K。以下 N 行每行两个整数 Wi 和 Vi。输出格式一个整数代表答案。样例输入3 10 3 5 10 4 9 3 8样例输出26提示选择第二件和第三件物品同时对第二件物品使用魔法。对于 30% 的数据1 ≤ N, M, K ≤ 100.对于 100% 的数据1 ≤ N ≤ 2000, 1 ≤ M, K ≤ 10000, 0 ≤ Wi , Vi ≤ 10000.import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.*; public class Main { static int N10010; static int v[]new int[N]; static int w[]new int[N]; static int c[]new int[N]; static int f[][]new int[N][2]; static int n; static BufferedReader br new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bwnew BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { StringTokenizer stnew StringTokenizer(br.readLine()); nInteger.parseInt(st.nextToken()); int m Integer.parseInt(st.nextToken()); int kk Integer.parseInt(st.nextToken()); for (int i 1; i n; i) { stnew StringTokenizer(br.readLine()); v[i]Integer.parseInt(st.nextToken()); w[i]Integer.parseInt(st.nextToken()); } //本题相对于零一背包问题多了一个状态也就是当前位置使用魔法的次数 //可以分为两种情况 当前位置是否使用魔法 注意只是当前位置 不代表之前所有 //定义f(i,j,k)为 考虑前i件物品 背包体积不超过j 一直到当前位置使用k次魔法的最大价值 //f[i][j][0]max(f[i-1][j][0],f[i-1][j-v][0]w); //计算f[i][j][1]这个 要分是否在本位置 使用魔法 //若不使用 f[i][j][1]max( f[i-1][j][1],f[i-1][j-v][1]w); //若使用 f[i][j][1]max(f[i][j][1],f[i-1][j-(vk)][1]2*w); for (int i 1; i n ;i) { for (int j m; j 0; j--) { //这里要注意 题目的重量可以等于0 if(j-v[i]0)f[j][0]Math.max(f[j][0],f[j-v[i]][0]w[i]); if(j-v[i]0)f[j][1]Math.max( f[j][1],f[j-v[i]][1]w[i]); if(j-(v[i]kk)0)f[j][1]Math.max(f[j][1],f[j-(v[i]kk)][0]2*w[i]); } } bw.write(Math.max(f[m][0], f[m][1])); br.close(); bw.flush(); bw.close(); } }砝码称重问题描述你有一架天平和 NN 个砝码这 NN 个砝码重量依次是 W1,W2,⋅⋅⋅,WNW1​,W2​,⋅⋅⋅,WN​。请你计算一共可以称出多少种不同的重量 注意砝码可以放在天平两边。输入格式输入的第一行包含一个整数 NN。第二行包含 NN 个整数W1,W2,W3,⋅⋅⋅,WNW1​,W2​,W3​,⋅⋅⋅,WN​。输出格式输出一个整数代表答案。样例输入3 1 4 6样例输出10样例说明能称出的 1010 种重量是1、2、3、4、5、6、7、9、10、111、2、3、4、5、6、7、9、10、11​。111126−4(26−4(天平一边放 66另一边放 4)4)​34−134−1444456−156−1​6666716716946−1946−11046104611146。11146。评测用例规模与约定对于 5050的评测用例1≤N≤151≤N≤15。对于所有评测用例1≤N≤100,N1≤N≤100,N​个砝码总重不超过 100000100000。import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.*; public class Main { static int N100010; static int w[]new int[N]; static boolean f[][]new boolean[110][N]; static int n; static BufferedReader br new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter bwnew BufferedWriter(new OutputStreamWriter(System.out)); public static void main(String[] args) throws IOException { StringTokenizer stnew StringTokenizer(br.readLine()); nInteger.parseInt(st.nextToken()); stnew StringTokenizer(br.readLine()); int sum0; for (int i 1; i n; i) { w[i]Integer.parseInt(st.nextToken()); sumw[i]; } //定义f[i][j]为只考虑前i件砝码 是否能称出重量j的重物 for (int i 0; i n; i) { f[i][0]true; } for (int i 1; i n; i) { for (int j 1; j sum; j) { //如果前 i-1 个砝码已经能称出重量 j那么不加第 i 个砝码自然也能称出 j f[i][j]|f[i-1][j]; //将第 i 个砝码放在重物j一侧 // 设想天平左边放重物未知重量右边放砝码。如果重物重量为 j第 i 个砝码放在重物同侧即和重物一起在左边 // 那么右边只需要平衡重量 j w[i] 即可因为左边总重 j w[i]右边为 j w[i] 时平衡。 if(j w[i]sum)f[i][j]|f[i-1][j w[i]]; //将第 i 个砝码与重物j不放在一侧 //设重物在左边重量为 j 第 i 个砝码放在右边 //如果砝码比重物轻 若想称出重物j 取决于能不能称出 j - w[i] if(j w[i])f[i][j]|f[i-1][j - w[i]]; //如果砝码比重物重 若想称出重物j 取决于能不能称出 w[i] - j else if(w[i] j)f[i][j]|f[i-1][w[i]-j]; } } int res0; for (int i 1; i sum; i) { if(f[n][i])res; } bw.write(res); br.close(); bw.flush(); bw.close(); } }

相关新闻

HarmonyOS APP实战-画图APP - 第8篇:图像效果应用(亮度/模糊/灰度)

HarmonyOS APP实战-画图APP - 第8篇:图像效果应用(亮度/模糊/灰度)

2026/9/7 22:50:41

HarmonyOS APP实战-画图APP - 第8篇:使用effectKit处理图像 1. 开篇 上一篇我们实现了在画布上添加文字的功能,用户可以通过对话框输入文字内容、选择字体大小和颜色,并通过拖拽将文字放置在画布任意位置。文字绘制基于CanvasRenderingContex…

HarmonyOS APP实战-画图APP - 第7篇:文本绘制功能

HarmonyOS APP实战-画图APP - 第7篇:文本绘制功能

2026/9/24 9:18:29

HarmonyOS APP实战-画图APP - 第7篇:在画布上添加文字 1. 开篇 在第6篇中,我们完成了绘制模式的切换与交互反馈优化。通过 DrawMode 枚举( Rect 、 Circle 、 FreeDraw )管理当前绘制模式,在工具栏中实现了高亮选中状态…

Open Source Candies生态系统分析:开源项目如何利用免费服务成长

Open Source Candies生态系统分析:开源项目如何利用免费服务成长

2026/9/1 11:23:48

Open Source Candies生态系统分析:开源项目如何利用免费服务成长 【免费下载链接】opensource-candies Free stuff for open source projects 项目地址: https://gitcode.com/gh_mirrors/op/opensource-candies 在开源项目的成长过程中,资源和工具…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/23 22:20:06

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/25 9:40:47

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/24 3:39:17

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/25 9:53:52

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/25 8:58:17

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/25 10:00:17

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/24 16:02:49

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/25 9:41:47

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/25 4:22:14

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…