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

贪心算法经典问题

目录

贪心思想

一、Dijkstra最短路问题

问题描述:

贪心策略:

二、Prim 和 Kruskal 最小生成树问题

Prim 算法:

Kruskal 算法:

三、Huffman树问题

问题描述:

贪心策略:

四、背包问题

问题描述:

贪心策略:

五、硬币找零问题

问题描述:

贪心策略:

六、区间合并问题

问题描述:

贪心策略:

七、选择不相交区间问题

问题描述:

贪心策略:

八、区间选点问题

问题描述

贪心策略

九、区间覆盖问题

问题描述:

贪心策略:

十、区间分组问题

问题描述:

贪心策略:

十一、任务调度问题

问题描述:

贪心策略:

十二、加油站问题

问题描述:

贪心策略:

十三、跳跃游戏

问题描述:

贪心策略:

十四、跳跃游戏 II

问题描述:

贪心策略:

 十五、股票买卖问题

问题描述:

贪心策略:

十六、最小代价贪心问题

问题描述:

贪心策略:

1.https://codeforces.com/contest/2118/problem/C

思路:

代码:

2.https://codeforces.com/contest/1722/problem/D

思路:

代码:

十七、其他

1.B-黄_牛客小白月赛118

思路:

代码:

2.https://codeforces.com/problemset/problem/2116/B

思路及代码:cf2116B-CSDN博客

3.https://codeforces.com/problemset/problem/2067/B

思路及代码:cf2067B-CSDN博客

4.https://codeforces.com/problemset/problem/2059/B

思路及代码:cf2059B-CSDN博客

5.https://codeforces.com/contest/1760/problem/E

思路:

代码:


贪心思想

        贪心算法(Greedy Algorithm)是一种在求解问题时,每一步都选择当前最优解,以期望最终得到全局最优解的算法思想。贪心算法的基本思想可以总结为“每一步都做出一个局部最优的选择,最终就能得到全局最优解”。

一、Dijkstra最短路问题

问题描述:

在一个图中,找到从起点到其他所有点的最短路径(适用于无负边权的情况)。

贪心策略:

每次扩展离源点最近的未访问节点。

二、Prim 和 Kruskal 最小生成树问题

Prim 算法:

从任意一个顶点开始,逐步加入与当前树连接权重最小的边。

Kruskal 算法:

按边权从小到大排序,依次加入不会形成环的边。

三、Huffman树问题

问题描述:

构造一个带权路径长度最小的二叉树,用于数据压缩中的最优前缀编码。

贪心策略:

每次合并两个频率最小的节点。

四、背包问题

问题描述:

物品可以取部分,目标是在容量限制下最大化总价值。

贪心策略:

按单位重量价值从高到低依次选取。

五、硬币找零问题

问题描述:

给定不同面值的硬币,求最少数量凑出某个金额。

贪心策略:

优先使用最大面值的硬币。

六、区间合并问题

问题描述:

给定多个区间,合并所有有重叠或相邻的区间,返回合并后的无重叠区间列表。

贪心策略:

按左端点排序后依次处理,若当前区间与结果中最后一个区间重叠,则合并。

七、选择不相交区间问题

问题描述:

给定多个时间区间,从中选择尽可能多的互不重叠的区间。

贪心策略:

按右端点从小到大排序,每次选择最早结束的区间,跳过与其冲突的区间。

八、区间选点问题

问题描述

在每个区间中至少选一个点,使得这些点覆盖所有区间,要求所选点的数量最少。

贪心策略

按右端点排序,每次在当前未被覆盖的区间的右端点上选一个点。

九、区间覆盖问题

问题描述:

给定一个目标区间和若干子区间,判断是否能用这些子区间完全覆盖目标区间。

贪心策略:

按左端点排序,从起点开始,每次选择能延伸最远的区间,逐步扩展覆盖范围。

十、区间分组问题

问题描述:

将一组区间分成若干个组,每组内的区间互不重叠,要求使用的组数最少。

贪心策略:

按左端点排序,使用最小堆维护各组的最早可用时间,优先将当前区间分配给最早空闲的组。

十一、任务调度问题

问题描述:

给定若干任务及其完成期限和利润,选择能获得最大利润的任务序列。

贪心策略:

按利润降序排序,依次尝试安排任务在最后可行的时间点。

十二、加油站问题

问题描述:

一辆车绕一圈油路,判断是否可以从某一点出发完成一圈,并找出该起点。

贪心策略:

维护当前油量和总油量,若当前油量为负则重新设置起点。

十三、跳跃游戏

问题描述:

数组中每个元素代表可跳跃的最大步数,判断是否可以到达最后一个位置。

贪心策略:

维护当前能跳到的最远位置,逐步推进。

十四、跳跃游戏 II

问题描述:

在跳跃游戏中,求最少跳跃次数到达终点。

贪心策略:

维护当前能跳的最远边界,以及下一步的最远可达。

 十五、股票买卖问题

问题描述:

允许多次买卖,但每次只能持有一股。

贪心策略:

只要第二天价格比今天高,就买入卖出。

十六、最小代价贪心问题

问题描述:

在有限操作次数内,通过优先选择代价最低的操作使目标值最大化。

贪心策略:

按操作代价从小到大依次选择操作,直到操作次数用尽。

1.https://codeforces.com/contest/2118/problem/C

思路:

        统计每个数字每一位变1的代价,排序取最小的 n 个即可。

代码:
void solve()
{ll n, k;cin >> n >> k;vector<ll> a(n + 10);cin >> a;vector<ll> v;ll ans = 0;for (ll i = 0; i < n; ++i){ll x = a[i];ll cnt = 0;for (ll j = 0; j < 63; ++j){if (x >> j & 1ll)ans++;elsev.pb(1ll << j);}}sort(all(v));for (auto x : v){if (k <= 0)break;if (k >= x){ans++;k -= x;}}cout << ans << endl;
}

2.https://codeforces.com/contest/1722/problem/D

思路:

        统计每个字符最大贡献与当前贡献的差值,排序即可。

代码:
void solve()
{int n;string s;cin >> n >> s;s = ' ' + s;ll ans = 0;vector<int> maxx(n + 10, 0);for (int i = 1; i <= n; ++i){if (s[i] == 'L'){maxx[i] = {abs(max(i - 1, (n - i)) - (i - 1))};ans += i - 1;}else{maxx[i] = {abs(max(i - 1, (n - i)) - (n - i))};ans += n - i;}}sort(maxx.begin() + 1, maxx.begin() + 1 + n, greater<int>());for (int i = 1; i <= n; ++i){ans += maxx[i];cout << ans << ' ';}cout << endl;
}

十七、其他

这类题目不是经典的贪心模型,但是解题思路是基于贪心策略的题目。

1.B-黄_牛客小白月赛118

思路:

        每次配对 a[i] 和 a[i + 1],如果不互质,就将 a[i + 1] 变为 1,因为 a[i] 在之前可能与其他的元素配对了,选择修改 a[i + 1] 是更优的。

代码:
void solve()
{int n;cin >> n;vector<ll> a(n + 10);for (int i = 0; i < n; ++i)cin >> a[i];ll ans = 0;for (int i = 0; i < n - 1; ++i){if (__gcd(a[i], a[i + 1]) != 1){a[i + 1] = 1;++ans;}}cout << ans << endl;
}

2.https://codeforces.com/problemset/problem/2116/B

思路及代码:cf2116B-CSDN博客

3.https://codeforces.com/problemset/problem/2067/B

思路及代码:cf2067B-CSDN博客

4.https://codeforces.com/problemset/problem/2059/B

思路及代码:cf2059B-CSDN博客

5.https://codeforces.com/contest/1760/problem/E

思路:

        题目要求统计i<j 且 a_i>a_j 的索引对数,由于只有 0、1 两种元素,所以只需统计 1 后面有几个 0 即可;我们还可以将 1 个元素取反,不难发现将第一个值为 0 的元素变 1 或最后一个值为1 的元素变 0 贡献最大,可证明该贪心策略成立,由于数据量不大,直接把三种情况都统计一遍即可(不变的也要统计)。

代码:
void solve()
{int n;cin >> n;vi a(n + 10), b;cin >> a;vi cnt1(n + 10, 0);int cur = 0;for (int i = n - 1; ~i; --i)if (a[i] == 0)++cur;elsecnt1[i] = cur;b = a;for (int i = 0; i < n; ++i)if (b[i] == 0){b[i] = 1;break;}vi cnt2(n + 10, 0);cur = 0;for (int i = n - 1; ~i; --i)if (b[i] == 0)++cur;elsecnt2[i] = cur;b = a;for (int i = n - 1; ~i; --i)if (b[i] == 1){b[i] = 0;break;}vi cnt3(n + 10, 0);cur = 0;for (int i = n - 1; ~i; --i)if (b[i] == 0)++cur;elsecnt3[i] = cur;ll ans1 = 0, ans2 = 0, ans3 = 0;for (int i = 0; i < n; ++i)ans1 += cnt1[i];for (int i = 0; i < n; ++i)ans2 += cnt2[i];for (int i = 0; i < n; ++i)ans3 += cnt3[i];cout << max({ans1, ans2, ans3}) << endl;
}

相关文章:

  • 【LoRA】怎么指定LoRAConfig的target_modules
  • 自动化立体仓库堆垛机控制系统STEP7 FC1功能块 读取位置值SSI接口
  • k8s使用私有harbor镜像源
  • 2025年生命科学突破奖: GLP-1 激素机制及应用,多发性硬化症(MS)致病机制的新发现
  • 暑期车辆违停治理:视觉算法的实践路径
  • 本地 MySQL 环境连接问题排查与解决笔记
  • 一起来入门深度学习知识体系
  • 卷积神经网络的参数量及尺度变化计算
  • 【文献阅读】5%>100%: 打破视觉识别任务的完全微调的性能束缚
  • 简说ping、telnet、netcat
  • OpenVINO使用教程--resnet分类模型部署
  • 将图片合成为视频(基于 OpenCV)
  • 【Redis】集群
  • 21 - GAM模块
  • 基于单片机的PT100温度变送器设计
  • 一个前端正则校验引发的问题
  • JavaScript基础-事件对象
  • 前端开发中,实现多线程
  • 又来交作业了
  • 探险之物资储备c++
  • 怎样做网站平台/广州新闻头条最新消息
  • 做推广哪个网站最好/百度网首页官网登录
  • 做网站优化的/百度地图轨迹导航
  • p2p网站建设/广东近期新闻
  • 湘潭网站优化/全网关键词云查询
  • 建设官方网站/百度竞价员