ACM算法训练【贪心合集】
贪心合集
- 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算法训练【贪心合集】相关推荐
- Open3D点云处理算法最全合集
Open3D点云处理算法最全合集,致力于搜集可运行,可视化较好的Open3D算法,持续更新中- 1. Open3D 点云读取及可视化.离群点去除 2. Open3D 点云体素格下采样 3. Open3 ...
- ACM算法训练【逆序对的数量】
ACM算法训练[逆序对的数量] 题目说明 数据范围 样例 分析与代码 题目说明 数据范围 样例 分析与代码 ①归并排序基本思想: ②在归并的过程中,逆序对出现的三种情况: a.全部出现在左边的区间 b ...
- ACM算法训练【模拟队列】
ACM算法训练[模拟队列] 1.题目 2.样例 3.代码 1.题目 2.样例 输入样例: 10 push 6 empty query pop empty push 3 push 4 pop query ...
- 算法基础课【合集1】
文章目录 基础算法 785. 快速排序 786. 第k个数 787. 归并排序 788. 逆序对的数量 789. 数的范围 790. 数的三次方根 791. 高精度加法 792. 高精度减法 793. ...
- 2018北大暑校acm算法训练课程 Tian Ji -- The Horse Racing 贪心
总时间限制: 5000ms 内存限制: 65536kB 描述 Here is a famous story in Chinese history. That was about 2300 years ...
- 算法基础课【合集2】
文章目录 数学知识 AcWing 866. 试除法判定质数 AcWing 867. 分解质因数 AcWing 868. 筛质数 AcWing 869. 试除法求约数 AcWing 870. 约数个数 ...
- 算法竞赛知识合集 目录(博客中转站)
目录 0x00. 基本算法 0x01. 基本算法 - 位运算 0x02. 基本算法 - 递推与递归 0x03. 基本算法 - 前缀和与差分 0x04.基本算法 - 二分和三分 0x05.基本算法 - ...
- 第一周一本通贪心合集
目录 1.家庭作业 2.加工生产调度 3.喷水装置 4.种树 5.活动安排3 6.线段 7.数列分段2 8.数列极差问题 9.糖果传递 10.钓鱼2 11.排队接水 12.智力大冲浪 13.均分纸牌 ...
- ACM算法训练赛——STL(完结)
STL训练赛 A - JiaoZhu and SC #include <bits/stdc++.h> #define int long long #define rep(i, a, b) ...
最新文章
- java 限制文本框长度_java中限制文本框输入长度的显示(转载)
- java 偏移符号_java中的移位运算符总结
- @kafkalistener中id的作用_SSM框架(十一):Spring框架中的IoC(1)
- css 解析器 java_Java 的 CSS 解析器 jStyleParser
- 分分钟甩Word几条街,Python编辑公式竟可以如此简单,你都知道吗?
- View Agent Direct-Connection安装后,连接黑屏
- 教你识别一些sequence的相关问题
- Python之数据分析(Numpy的数组切片、数组变维、组合与拆分)
- AtCoder 杂题训练
- 智能时代“云”主沉浮
- 计算机word英语词汇大全,Microsoft Word - 计算机英语词汇汇总.pdf
- python补考卷子_1819级计算机专业补考(python程序设计)_章节测验,期末考试,慕课答案查询公众号...
- 2018年,Windows Phone 8.1还能做什么
- 电脑硬盘主分区和逻辑分区的区别是什么
- [七七黎]乱七八糟-美女和野兽
- 17个小时内,各地相继出手帮中小企业,地产商减租百亿
- 10个最好的免费PS图象处理软件方案
- 小程序获取本地存储数据,然后传参的时候是上次请求的id
- Struts2介绍(一个大的工具库)
- 在centos7中基于nginx-rtmp模块的mp4播放