1.活动安排。计算可参加的最大活动数

题目:
  有个叫做“嘻哈华”的同学,他所在的学校将举办一次活动,现在他想知道一个教室最多能安排的活动数?现在告诉他活动开始时间与结束时间,问:最多活动数?
思路:
  这个时间可以是数字,也可以是字符串形式如“11:25”或者“03:21”,注意到我们可以用sort对字符串进行排序,只要他们是长度相同的,尽管中间有:但是都有那就相同不会影响的!!!所以遇到这种输入不要慌!直接排序
  这个题目的思路就是贪心原则,自定义排序规则对时间的结尾进行排序,结尾越靠近前面就排序到前面,就是对结尾从小到大排序。贯彻贪心原则,这个是符合贪心的。如果有最靠前的结尾,为什么不选! 不然选择靠后的结尾,在后面选择的时候就少了很多时间了!
  方便理解就是,我总要参加活动,每个活动都有结束时间,我为了最大化安排,肯定先看哪个活动先结束。然后再看后面的活动开始时间是不是大于结束时间,如果是就参加。不是就看后面的

#include<bits/stdc++.h>
using namespace std;
bool cmp(vector<string>x,vector<string>y){
	return x[1]<y[1];
}
int main(){
	string s1;
	vector<vector<string>> temp(3,vector<string>(2));
	for(int i=0;i<3;i++){
		string t;
		vector<string>tt;
		getline(cin,s1);
		stringstream ss(s1);
		while(getline(ss,t,' '))
			tt.push_back(t); //二维的话增加一个辅助,不能用temp[i]  
		temp[i]=tt;
	
	}
	/完成输入
	
	int ans=1;
	sort(temp.begin(),temp.end(),cmp); 
	string end=temp[0][1];
	for(int i=1;i<temp.size();i++){
		if(temp[i][0]>=end){
			ans++;
			end=temp[i][1];
		}
	}
	cout<<ans;
}

或者 ,也就是说push_back是在没分配的空间内增加,你提前给他增加了2,默认是0的,你push在外围了!!!

#include<bits/stdc++.h>
using namespace std;
bool cmp(vector<string>x,vector<string>y){
	return x[1]<y[1];
}
int main(){
	string s1;
	vector<vector<string>> temp(3);
	for(int i=0;i<3;i++){
		string t;
		vector<string>tt;
		getline(cin,s1);
		stringstream ss(s1);
		while(getline(ss,t,' '))
			temp[i].push_back(t);
		//cout<<temp[0][0];
		
	
	}
	/完成输入
	
	int ans=1;
	sort(temp.begin(),temp.end(),cmp); 
	string end=temp[0][1];
	for(int i=1;i<temp.size();i++){
		if(temp[i][0]>=end){
			ans++;
			end=temp[i][1];
		}
	}
	cout<<ans;
}

——————————————————————————————————————————————————————变体:
1353. 最多可以参加的会议数目
在这里插入图片描述
  在这里插入图片描述
思路:
   注意到,这个题目和上面的题目不同在于,上面的题目不允许重合,而这个题目允许重合,比如1,4天内选择一天,2,3天内选择一天,他们重合了,但是都可以参加。这样贪心算法就不能从尾巴入手了
   这个题目可以通过这样的手段来解决。我们首先用一个哈希表建立开始时间和结束时间的映射,就是某个开始时间肯定有若干个结束时间,注意到这里的若干个,对应了若干个会议了!!!! 也就是说我们找出同一个时间开始的会议 ,很明显哪个会议先结束,我们就去参加哪个会议,这是属于这个时间内去参加会议的最大收益了!!
   遍历时间点,看这个时间点是否有会议开展,如果有,进入最小队列
   因为之前也有会议进入我们的最小队列,只是结束时间太迟了,没参加,如果到今天发现已经有会议结束了,那就要出栈
   然后看下队列中结束时间最小的会议,咱们去参加结束时间最短的会议!!!然后会议次数+1;
   
我也用了类似的解决方式,首先把当前day能够参加的会议全部丢进一个结束时间的小根堆中,这样最顶上的会议就会是先结束的,先结束的肯定是要先做的,这是贪心策略,因为后结束的在之后还有机会做。因为每天只能参加一个会议,所以从结束栈顶弹出一个参加,重复这些操作最后等所有会议都过期或者参加了就结束了。这个策略为什么可行,比如第一天1,1或者1 4 如果第四天结束我可以缓缓,如果第一天结束,那我为什么不参加;但是比如第一天参加的会议1:4天都行 出栈呗,反正今天能!!!!注意到一旦count了,表示今天肯定肯定是可以参加会议的,看下今天如果是2 2不用多说,如果是2 1,这个1比2要小,过期了就不参加了;比如2 4 2 3,在队列,那我就出这个3,其实这个出就是说把这个会议给他解决了,后面的数字只是轻重缓急!!!别被迷惑了,因为3,剩下的4你可以明天参加啊或者后天

class Solution {
public:
    int maxEvents(vector<vector<int>>& events) {
        int maxDay = 0;
        // 构建一个【开始天】 和 【结束天】的映射
        unordered_map<int, vector<int>> day2days;
        for (vector<int>& event : events)
        {
            if (maxDay < event[1])
            {
                maxDay = event[1]; //最多有这么多天
            }
            day2days[event[0]].push_back(event[1]);
        }
        // 记录参见会议的次数
        int res = 0;
        // 小顶堆队列
        priority_queue<int, vector<int>, greater<int>> q;
        for (int i = 1; i <= maxDay; ++i) //看看这么多天那一天参加会议
        {
            // 增加新的结束时间
            if (day2days.count(i)) //如果找到i
            {
                for (int day : day2days[i]) //结束天入队列
                    q.push(day);  
            }

            // 删除队列里结束时间小于i的会议:因为它们已经结束了,无法再选择
            while (!q.empty() && q.top() < i)
            {
                q.pop();
            }

            // 直接取最小结束时间会议,次数+1
            if (!q.empty())
            {
                q.pop();
                ++res;
            }
        }
        return res;
    }
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值