蓝桥杯备考---贪心

应用空间:只需考虑当前最优解无需考虑是否影响整体最优解就可以得到最好的结果

相关练习:洛谷p2240 --- 注意排序 备好基础的选择排序 冒泡排序 以及 sort调用的判断函数用法                      熟悉结构体的用法

                  选择排序模板

                  冒泡排序模板

                  sort条件判断:sort(begin, end, cmp) cmp不填默认升序 

#include<iostream>
#include<algorithm>
using namespace std;
//若想要得到降序序列 则两个数比较 较大返回true
bool cmp(int a, int b){
	return a > b;
}
int main(){
	int a[10] = {2,6,8,4,10,12,3,5};
	sort(a, a + 8, cmp);
	for(int i = 0; i < 8; i ++)
		cout << a[i] << endl;
}

                   结构体命名

typedef struct student{
	int age;
	string name;
}stu;//别名 代表struct student 方便创建变量

stu zhy;
zhy.age = ...

struct student{
	int age;
	string name;
}zhy;//zhy 一个student类型的变量

                    洛谷p1224 --- 注意个人等待时间里不计入自己的接水时间

                    洛谷p1803 --- 题意:给出一组比赛及开始结束时间 问最多可参加多少场

思路1 --- 全部按开始时间排序 受参考样例的迷惑 以为比赛时长均一致 失败

思路2 --- 按比赛时长排序 来一个一维数组记录报名的比赛时间段  关于打表做记录存在一定问题 

参考1 --- 参照评论区题解 本题是经典的贪心算法中的选择不相交区间的问题,在《算竞入门》中也介绍过,无论如何,选择结束点最靠前的区间总是最好的(算竞入门是什么鬼 我怎么都没听说过) 按照比赛的结束时间进行排序 若两场比赛无交叉 直接报名 若当前比赛与上场比赛有交叉 则该比赛不报名 因为明显结束时间晚 若替换前一场比赛 会更加影响后续比赛的报名 并不是最优选择

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6 + 10;
typedef struct contest{
	int begin, end;	
}CTT; 
bool cmp(CTT x, CTT y){
	return x.end  < y.end;
}
CTT ct[N];
int main(){
	int n;
	cin >> n;
	for(int i = 0; i < n; i ++)
		cin >> ct[i].begin >> ct[i].end;
	sort(ct, ct + n, cmp);
	int res = 1;
	int flag = ct[0].end;
	for(int i = 1; i < n; i ++){
		if(ct[i].begin >= flag){
			res ++;
			flag = ct[i].end;
		}
	}
	cout << res;
}

参考2 --- 跟思路1一致 按开始时间来排序 循环比较两场比赛的结束时间 若当前比赛与上一场比赛无交叉 直接报名 若当前比赛与上一场比赛有交叉 谁先结束报哪个 此时可能要更新要比较的最近结束时间 报名场次无需更新

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6 + 10;
typedef struct contest{
	int begin, end;	
}CTT; 
bool cmp(CTT x, CTT y){
	return x.begin  < y.begin;
}
CTT ct[N];
int main(){
	int n;
	cin >> n;
	for(int i = 0; i < n; i ++)
		cin >> ct[i].begin >> ct[i].end;
	sort(ct, ct + n, cmp);
	int res = 1;
	int flag = ct[0].end;
	for(int i = 1; i < n; i ++){
		if(ct[i].begin >= flag){//两场比赛没有交叉 
			res ++;
			flag = ct[i].end;
		}
		else{
			if(ct[i].end < flag){//第二场比赛比前一场晚开始早结束  两场比赛进行替换  
				flag = ct[i].end;//更新比赛的最近结束时间 
			}
		}
	}
	cout << res;
}

                        洛谷p3817 --- 提别提醒 注意数据范围 不开longlong见祖宗 虽然这道题应该是数据范围给错了 不过还是要特别注意一下

                        洛谷p1090 --- 没有解决 看ppt答案感觉能勉强理解但完全想不到 感觉第二个数组用的很别扭 看题解区大佬都提到优先队列 小根堆。。。 还是之后补完相关知识再解这道题吧

                        洛谷p4995 --- 类似1090的想法 采用两个数组 一个升序一个降序 轮流跳跃来消耗体力 一次就ac

暂时更新到这 打完icpc网络赛去看acwing的贪心再补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值