当前位置: 首页 > news >正文

01背包问题合集 蓝桥OJ

一、蓝桥OJ 1174小明的背包1 模板题

思路:

用二维数组dp判断最大价值,i表示物品数量,j表示物品体积,如果 j > V 则无需继续, j >= w 物品还能再增加,同样价值也增加,否则继承之前的价值,在之间找Max,最大价值。

#include<bits/stdc++.h>
using namespace std;const int N = 1e3 + 4;
int dp[N][N];int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n, V; cin >> n >> V;for(int i = 1; i <= n; i++){int w, v; cin >> w >> v;for (int j = 1; 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] << '\n';return 0;
}

优化思路:

避免新数据更新为新数据。上面的代码每次j的下标都是从小到大, 故可以直接当作一个数组,每次更新时,从后往前更新。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 4;
int dp[N];int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n, V; cin >> n >> V;for (int i = 1; i <= n; i++){int w, v;cin >> w >> v;for (int j = V; j >= w; j--){dp[j] = max(dp[j], dp[j-w]+v);}}cout << dp[V] << '\n';return 0;
}

二、蓝桥OJ 2223背包与魔法

思路:

这道题可以分成三类,1.不选 2.选但不用魔法 3.选且用魔法, 三种中取最大价值的。 

#include<bits/stdc++.h>
using namespace std;const int N = 1e4+5;
int dp[N][2]; // 0的时候表示魔法已用,1表示魔法没用int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n, m, k; cin >> n >> m >> k;for (int i = 1; i <= n; i++){int w, v; cin >> w >> v;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]) << '\n';return 0;
}

三、蓝桥OJ 3741倒水

思路:

用一个二维dp数组记录所有满意度之和的最大值,dp[i][j]中的i表示1~i个客人,j表示 倒水j毫升。

分3种情况,是否倒着写要看情况:

1.当j < a时,dp[i][j] = dp[i-1][j]+e

2.当j >= a and j < c时, dp[i][j] = max(dp[i-1][j]+e, dp[i-1][j-a]+b)

3.当j>=c时, dp[i][j] = max(dp[i-1][j-c]+d , max(dp[i-1][j]+e, dp[i-1][j-a]+b))

下面的代码第一次写忘记了开long long!!!一定要记住 

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e3 + 8;
ll dp[N][N];int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n, m; cin >> n >> m;for (int i = 1; i <= n; i++){int a, b, c, d, e;cin >> a >> b >> c >> d >> e;for (int j = 0; j <= m; j++){if (j < a) dp[i][j] = dp[i-1][j]+e;else if (j >= a && j < c) dp[i][j] = max(dp[i-1][j]+e,dp[i-1][j-a]+b);else if (j >= c) dp[i][j] = max(dp[i-1][j-c]+d, max(dp[i-1][j]+e,dp[i-1][j-a]+b));}}cout << dp[n][m] << '\n';return 0;
}

 四、蓝桥OJ 3637盗墓分赃2

尽量把数组开大一点,不然会有测试点错误。

思路:

01背包的变形,宝藏的重量即宝藏的价值,当宝藏的重量和为奇数,一定不能平均的分成两份。后面跟01背包一样

#include<bits/stdc++.h>
using namespace std;
const int N = 2e4 + 8;
int a[N],dp[N];int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n;cin >> n;int sum = 0;for (int i = 1; i <= n; i++){cin >> a[i];sum += a[i];}if (sum&1){cout << "no" << '\n';return 0;}sum = sum / 2;for (int i = 1; i <= n; i++){for (int j = sum; j >= a[i]; j--){dp[j] = max(dp[j],dp[j-a[i]]+a[i]);}}string res = (dp[sum] == sum) ? "yes": "no";cout << res << '\n';return 0;
}

五、蓝桥OJ 5118小兰的神秘礼物

跟 盗墓分赃 一模一样 

#include<bits/stdc++.h>
using namespace std;
const int N = 1e3 + 8;
int x[N], dp[N];int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int V; cin >> V;//箱子的容量int n; cin >> n;//收集的小物件总数for (int i = 1; i <= n; i++) cin >> x[i];for (int i = 1; i <= n; i++)for (int j = V; j >= x[i]; j--) dp[j] = max(dp[j],dp[j-x[i]]+x[i]);cout << V-dp[V] << '\n';return 0;
}

http://www.lryc.cn/news/334990.html

相关文章:

  • Nuxt3 实战 (三):使用 release-it 自动管理版本号和生成 CHANGELOG
  • 鸿蒙OS开发实战:【自动化测试框架】使用指南
  • 算法(二分查找)
  • 运筹学基础(六)列生成算法(Column generation)
  • [阅读笔记] 电除尘器类细分市场2023年报
  • Kubernetes学习笔记11
  • ✌2024/4/3—力扣—无重复字符的最长子串
  • Tauri 进阶使用与实践指南
  • 2024年最新社交相亲系统源码下载
  • git知识
  • 代码随想录算法训练营第三十五天|860.柠檬水找零、406.根据身高重建队列、452.用最少数量的箭引爆气球
  • golang defer实现
  • 数据仓库实践
  • 深入浅出 -- 系统架构之微服务标准组件及职责
  • IP协议中的四大支柱:DHCP、NAT、ICMP和IGMP的功能剖析
  • 基于Socket简单的UDP网络程序
  • 计算机思维
  • 如何判断一个linux机器是物理机还是虚拟机
  • python用requests的post提交data数据以及json和字典的转换
  • 【Datax分库分表导数解决方法】MySQL_to_Hive
  • Vue2 —— 学习(一)
  • Windows Server 2008添加Web服务器(IIS)、WebDAV服务、网络负载均衡
  • SpringMVC转发和重定向
  • 勒索病毒最新变种.rmallox勒索病毒来袭,如何恢复受感染的数据?
  • 复试专业课问题
  • 比特币革命:刚刚开始
  • 淘宝店商家电话提取软件操作经验
  • 【进阶六】Python实现SDVRPTW常见求解算法——遗传算法(GA)
  • 【Android】App通信基础架构相关类源码解析
  • 06-kafka配置