贪心合集

  • 1.区间选点(区间问题·贪心)
  • 2.区间分组(区间问题·贪心)
  • 3.区间覆盖(区间问题·贪心)
  • 4.耍杂技的牛(权重相加问题·贪心)
  • 5.合并果子(Huffman树)
  • 6.排队打水(排序不等式)
  • 7.货舱选址(绝对值不等式)

1.区间选点(区间问题·贪心)

思路:

①将每个区间按右端点进行排序
②从前往后依次遍历每个区间
③如果当前区间已经被点覆盖,则pass,否则选择区间的最右边的点
④贪心的思想:每次选择局部最优点解,总体达到全部最优解(只有当问题是单峰的情况才可以使用贪心算法)

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
vector<PII> ports;
bool cmp(PII a,PII b)   //按pair的second排序
{return a.second < b.second;
}
int main()
{int n;cin>>n;for(int i=0;i<n;i++){int l,r;scanf("%d%d",&l,&r);ports.push_back({l,r});}sort(ports.begin(),ports.end(),cmp);int ans=0,ed=-2e9;for(auto item : ports)if(item.first>ed){ans++;ed=item.second;}cout<<ans;return 0;
}

2.区间分组(区间问题·贪心)

思路:

①所有区间按照左端点从小到大排序
②从前往后处理每个区间,对于每个区间,判断能否将其放到某个组中(L[i] <= Max_r)
不存在这样的组,开辟一个新的组;存在这样的组,放在这个组中,并且更新当前组的Max_r

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
struct Range
{int l,r;
}range[N];
bool cmp(Range a,Range b)   //结构体自定义排序
{return a.l<b.l;
}
int main()
{int n;cin>>n;for(int i=0;i<n;i++){int l,r;scanf("%d%d",&l,&r);range[i]={l,r};}sort(range,range+n,cmp);priority_queue<int,vector<int>,greater<int>> heap;  //定义小根堆for(int i=0;i<n;i++)if(heap.empty()||heap.top()>=range[i].l) heap.push(range[i].r);else{heap.pop();heap.push(range[i].r);}cout<<heap.size();return 0;
}

3.区间覆盖(区间问题·贪心)


输入样例:

1 5
3
-1 3
2 4
3 5

输出样例:

2

思路:

①将区间按左端点从小到大排序
②从前往后依次枚举每个区间,在所有能覆盖线段开头start的区间中选择一个右端点最大的
选完后将start更新成右端点的最大值

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
struct Range
{int l,r;
}range[N];
bool cmp(Range a,Range b)
{return a.l<b.l;
}
int main()
{int st,ed;cin>>st>>ed;int n;cin>>n;for(int i=0;i<n;i++){int l,r;scanf("%d%d",&l,&r);range[i]={l,r};}sort(range,range+n,cmp);int res=0;bool flag=false;for(int i=0;i<n;i++){int j=i,r=-2e9;while(j<n && range[j].l<=st){r=max(r,range[j].r);j++;}res++;if(r<st) break;if(r>=ed){flag=true;break;}i=j-1;st=r;}if(flag) cout<<res;else cout<<-1;return 0;
}

4.耍杂技的牛(权重相加问题·贪心)


数据范围

1≤N≤50000,
1≤Wi≤10,000,
1≤Si≤1,000,000,000

输入样例:

3
10 3
2 5
3 3

输出样例:

2

思路:

按照wi+si从小到大排序排,结果一定是最优解

#include <bits/stdc++.h>
using namespace std;
const int N = 50010;
struct Cow
{int w,s,total;
}cow[N];
bool cmp(Cow a,Cow b)
{return a.total<b.total;
}
int main()
{int n;cin>>n;for(int i=0;i<n;i++){int w,s;scanf("%d%d",&w,&s);cow[i]={w,s,w+s};}sort(cow,cow+n,cmp);int ans=-2e9,sum=0;for(int i=0;i<n;i++){ans=max(ans,sum-cow[i].s);sum+=cow[i].w;}cout<<ans;return 0;
}

5.合并果子(Huffman树)

在一个果园里,达达已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。

达达决定把所有的果子合成一堆。

每一次合并,达达可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。

可以看出,所有的果子经过 n−1 次合并之后,就只剩下一堆了。

达达在合并果子时总共消耗的体力等于每次合并所耗体力之和。

因为还要花大力气把这些果子搬回家,所以达达在合并果子时要尽可能地节省体力。

假定每个果子重量都为 1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使达达耗费的体力最少,并输出这个最小的体力耗费值。

例如有 3 种果子,数目依次为 1,2,9。

可以先将 1、2 堆合并,新堆数目为 3,耗费体力为 3。

接着,将新堆与原先的第三堆合并,又得到新的堆,数目为 12,耗费体力为 12。

所以达到总共耗费体力=3+12=15。

可以证明 15 为最小的体力耗费值。

输入样例:

3
1 2 9

输出样例:

15

每次选权重最小的两堆合并,结果就是全局最优解

#include <bits/stdc++.h>
using namespace std;int main()
{int n;cin>>n;priority_queue<int,vector<int>,greater<int>> heap;for(int i=0;i<n;i++){int a;scanf("%d",&a);heap.push(a);}int ans=0;while(heap.size()>1){int a=heap.top(); heap.pop();int b=heap.top(); heap.pop();ans+=a; ans+=b;heap.push(a+b);}cout<<ans;return 0;
}

6.排队打水(排序不等式)

输入样例:

7
3 6 1 4 2 5 7

输出样例:

56

排序相加策略:

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N];
int main()
{int n;cin>>n;for(int i=0;i<n;i++)scanf("%d",&a[i]);sort(a,a+n);long long ans=0;for(int i=0;i<n;i++)ans+=a[i]*(n-i-1);cout<<ans;return 0;
}

7.货舱选址(绝对值不等式)


输入样例:

4
6 2 9 1

输出样例:

12

各个货舱的点距离所有货舱的中位数距离最近:

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N];
int main()
{int n;cin>>n;for(int i=0;i<n;i++) scanf("%d",&a[i]);sort(a,a+n);long long ans=0;for(int i=0;i<n;i++)ans+=abs(a[i]-a[n/2]);cout<<ans;return 0;
}

ACM算法训练【贪心合集】相关推荐

  1. Open3D点云处理算法最全合集

    Open3D点云处理算法最全合集,致力于搜集可运行,可视化较好的Open3D算法,持续更新中- 1. Open3D 点云读取及可视化.离群点去除 2. Open3D 点云体素格下采样 3. Open3 ...

  2. ACM算法训练【逆序对的数量】

    ACM算法训练[逆序对的数量] 题目说明 数据范围 样例 分析与代码 题目说明 数据范围 样例 分析与代码 ①归并排序基本思想: ②在归并的过程中,逆序对出现的三种情况: a.全部出现在左边的区间 b ...

  3. ACM算法训练【模拟队列】

    ACM算法训练[模拟队列] 1.题目 2.样例 3.代码 1.题目 2.样例 输入样例: 10 push 6 empty query pop empty push 3 push 4 pop query ...

  4. 算法基础课【合集1】

    文章目录 基础算法 785. 快速排序 786. 第k个数 787. 归并排序 788. 逆序对的数量 789. 数的范围 790. 数的三次方根 791. 高精度加法 792. 高精度减法 793. ...

  5. 2018北大暑校acm算法训练课程 Tian Ji -- The Horse Racing 贪心

    总时间限制: 5000ms 内存限制: 65536kB 描述 Here is a famous story in Chinese history. That was about 2300 years ...

  6. 算法基础课【合集2】

    文章目录 数学知识 AcWing 866. 试除法判定质数 AcWing 867. 分解质因数 AcWing 868. 筛质数 AcWing 869. 试除法求约数 AcWing 870. 约数个数 ...

  7. 算法竞赛知识合集 目录(博客中转站)

    目录 0x00. 基本算法 0x01. 基本算法 - 位运算 0x02. 基本算法 - 递推与递归 0x03. 基本算法 - 前缀和与差分 0x04.基本算法 - 二分和三分 0x05.基本算法 - ...

  8. 第一周一本通贪心合集

    目录 1.家庭作业 2.加工生产调度 3.喷水装置 4.种树 5.活动安排3 6.线段 7.数列分段2 8.数列极差问题 9.糖果传递 10.钓鱼2 11.排队接水 12.智力大冲浪 13.均分纸牌 ...

  9. ACM算法训练赛——STL(完结)

    STL训练赛 A - JiaoZhu and SC #include <bits/stdc++.h> #define int long long #define rep(i, a, b) ...

最新文章

  1. java 限制文本框长度_java中限制文本框输入长度的显示(转载)
  2. java 偏移符号_java中的移位运算符总结
  3. @kafkalistener中id的作用_SSM框架(十一):Spring框架中的IoC(1)
  4. css 解析器 java_Java 的 CSS 解析器 jStyleParser
  5. 分分钟甩Word几条街,Python编辑公式竟可以如此简单,你都知道吗?
  6. View Agent Direct-Connection安装后,连接黑屏
  7. 教你识别一些sequence的相关问题
  8. Python之数据分析(Numpy的数组切片、数组变维、组合与拆分)
  9. AtCoder 杂题训练
  10. 智能时代“云”主沉浮
  11. 计算机word英语词汇大全,Microsoft Word - 计算机英语词汇汇总.pdf
  12. python补考卷子_1819级计算机专业补考(python程序设计)_章节测验,期末考试,慕课答案查询公众号...
  13. 2018年,Windows Phone 8.1还能做什么
  14. 电脑硬盘主分区和逻辑分区的区别是什么
  15. [七七黎]乱七八糟-美女和野兽
  16. 17个小时内,各地相继出手帮中小企业,地产商减租百亿
  17. 10个最好的免费PS图象处理软件方案
  18. 小程序获取本地存储数据,然后传参的时候是上次请求的id
  19. Struts2介绍(一个大的工具库)
  20. 在centos7中基于nginx-rtmp模块的mp4播放

热门文章

  1. MySQL创建/查看/修改/删除数据库
  2. Oracle-存储过程语法
  3. PLP: 4.2/4.3 Attribute Gramma阅读笔记3
  4. 【下一步计划】毕业后
  5. 【年度总结】满船清梦压星河
  6. 二分法查找最多查找几次
  7. 开源OA:手把手教你搭建OA办公系统(3)开发企业报销审批流程
  8. git bash返回上一级目录
  9. MySQL中GROUP_CONCAT函数的使用,separator,将多行查询结果用特定字符串连接起来,适用于一对多
  10. 韩顺平--IO流专题