NYOJ-14 会场安排问题(经典贪心,区间完全不覆盖模板)

附另一:此类问题选题总结:https://blog.csdn.net/qq_41289920/article/details/81001357

题干:

会场安排问题
时间限制:3000 ms | 内存限制:65535 KB
难度:4
描述
学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。小刘的工作就是安排学校小礼堂的活动,每个时间最多安排一个活动。现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排。
输入
第一行是一个整型数m(m<100)表示共有m组测试数据。
每组测试数据的第一行是一个整数n(1<n<10000)表示该测试数据共有n个活动。
随后的n行,每行有两个正整数Bi,Ei(0<=Bi,Ei<10000),分别表示第i个活动的起始与结束时间(Bi<=Ei)
输出
对于每一组输入,输出最多能够安排的活动数量。
每组的输出占一行
样例输入
2
2
1 10
10 11
3
1 10
10 11
11 20
样例输出
1

2

提示注意:如果上一个活动在t时间结束,下一个活动最早应该在t+1时间开始



解题报告:

以下给出三种方法,,只有一种是正确的 。

    1.按照start从小到大排同时end从小到大,然后0~n-1遍历。

    2.按照end从大到小排同时start从大到小排,然后0~n-1遍历。

    3.按照end从小到大排同时start从小到大排(其实start无所谓),然后0~n-1遍历。

   不难看出,只有3是成立的。    

证明:首先1和2肯定是绑定的,即如果成立均成立,如果不立均不立。因为其实模拟一组样例画出图来之后倒着看,1和2的方法是一模一样的,或者说,在1中找到一组样例否定掉这种方法,那么样例倒过来之后也可以否定掉第二种方法。

所以下证方法1是错误的:

    证明是错误的方法很简单,找一个特例否定掉他:(下面给的是排完序后的)

            1,5

            6,100

            7,9

            11,13

            15,16

显然。

下证方法3是正确的:

************************************************************************************

经典的区间贪心问题。将每个区间按右端点进行排序,每次第一个区间一定要选,然后重新确定起点,再第一个一定要选。

证明如下:设前两个区间为(a1, b1), (a2, b2),且b1<b2(即已经按b排好序了)

(1)当b1<a2

这种情况区间1和区间2不冲突,这样做一定是对的

(2)当第一个区间与其他区间起冲突了,而且第一个区间可能与很多区间同时起冲突了。但是所以这些起冲突的区间只能取一个。对于第一个区间要么取要么不取两个情况      

1)如果最后答案里有这个区间,先取后取一个样的,那么还不如第一下就取了

2)假设最后答案里没有这个区间,我们能推出矛盾,那不就说明“最后答案里没有这个区间“这个假设是错的。因为刚开始起冲突的那些区间一定只能选一个,如果你选了其他,可是这个区间一定可以被第一个替换掉,所以最后答案里又会出现第一个区间。

(证明选自:https://blog.csdn.net/shiwaigaoren12345/article/details/50767381)

所以是正确的。

*************************************************************************************

下面给出三种方法的代码:

方法1:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;struct Node {int s,e;
} node[10000 + 5];
//贪心排序起点做不出来!需要排end! 
bool cmp(const Node & a, const Node & b) {if(a.s!=b.s) return a.s<b.s;else return a.e<b.e;
}
int main()
{int m,n;scanf("%d",&m);while(m--) {scanf("%d",&n);for(int i = 0; i<n; i++) {scanf("%d %d",&node[i].s,&node[i].e);	}sort(node,node+n,cmp);int curs=node[0].s;int cure=node[0].e;int ans=1;int i = 1;while(i<n) {if(node[i].s==node[i-1].s) {curs=node[i].s;cure=min(cure,node[i].e);continue;}if(node[i].s>cure) {ans++;cur}}}return 0 ;
}

没有写完,,,因为写不动了,,,即 很早的发现了错误。。

方法2:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;struct Node {int s,e;
} node[10000 + 5];
//贪心排序起点做不出来!需要排end! 这样做从大到小排 依然是错的,因为和排start一样了啊。。你倒着看看 ,画个图 
bool cmp(const Node & a, const Node & b) {if(a.e!=b.e) return a.e>b.e;else return a.s>b.s;
}
int main()
{int m,n;
//	freopen("in.txt","r",stdin);scanf("%d",&m);while(m--) {scanf("%d",&n);for(int i = 0; i<n; i++) {scanf("%d %d",&node[i].s,&node[i].e);	}sort(node,node+n,cmp);
//		for(int i = 0; i<n; i++) {
//			printf("%d         %d\n",node[i].s,node[i].e);
//		}int curs=node[0].s;int cure=node[0].e;int ans=1;int i = 1;while(i<n) {if(node[i].e==node[i-1].e) {cure=node[i].e;curs=max(curs,node[i].s);i++;continue;}if(node[i].e<curs) {ans++;cure=node[i].e;curs=node[i].s;i++;}else {i++;}}printf("%d\n",ans);}return 0 ;
}
这种方法仔细分析会发现就是第一种方法。。


方法3:(ac代码)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;struct Node {int s,e;
} node[10000 + 5];
//贪心排序起点做不出来!需要排end! 并且是小到大排 !! 
bool cmp(const Node & a, const Node & b) {if(a.e!=b.e) return a.e<b.e;else return a.s>b.s;//其实这句就没用了 
}
int main()
{int m,n;
//	freopen("in.txt","r",stdin);scanf("%d",&m);while(m--) {scanf("%d",&n);for(int i = 0; i<n; i++) {scanf("%d %d",&node[i].s,&node[i].e);	}//养成输入完接着就排序的好习惯,若是放在while前面,,对于本题那就错了!! sort(node,node+n,cmp);int curs=node[0].s;//其实curs全程没用,可以删掉。 int cure=node[0].e;int ans=1;int i = 1;while(i<n) {//如果是 if(node[i].e==node[i-1].e)就错了、、、 //并且这个if可以删掉、、if(node[i].e==cure) {cure=node[i].e;curs=max(curs,node[i].s);i++;continue;}if(node[i].s>cure) {ans++;			 cure=node[i].e;//思想的精华!!curs=node[i].s;//curs依旧是,,没啥用、、、 i++;}else {i++;}}printf("%d\n",ans);}return 0 ;
}		

总结

1.上面这一步就看出 升序排end并且从0递归到n-1的妙处了!!

2.做题方法:先读题并确定需要找出的是什么(即以什么变量为中心点)!

此题根据题意你需要找出的是,每一步的end都是最小的那个(最优解),所以对end排序。
因为你每确定出一个ans,都能保证此时的end是最小的!而start是否满足,不用排序出来,而是if判断一步就好了啊。所以这题关键不是start而是end!(最后一段的理解可以看一下上面我给的样例) 
3.对于sort排序,一定要找清楚位置,不然很容易犯很低级的错误并且很难查出来

4.if判断啊逻辑关系要找清楚,第一个if那里,就一直写错了,

            写成了if(node[i].e==node[i-1].e)。所以这个if还不如不要,,,反正不影响程序、


5.送上 区间完全不覆盖 模板。

核心语句:

/*		for(i=0; i<n; i++){if(node[i].s>cure){ans++;cure=node[i].e;}}
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442157.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

可以使用田忌赛马类贪心问题的前提(或说 如何判断题目符合田忌赛马类贪心问题)

前提就是&#xff0c;首先&#xff0c;需要两个数组&#xff01;&#xff01;两个数组&#xff01;&#xff01;两个数组&#xff01;&#xff01;才可以考虑这个&#xff01; 其次&#xff0c;A和B这两个数组的个数是相同的。也正因为如此&#xff0c;所以从大到小排序或者从小…

【nyoj 270】数的分解(统计因子模板)

题干&#xff1a; 数的分解时间限制&#xff1a;1000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;1描述你的任务是找到一个最小的正整数Q&#xff0c;使Q的各位数的乘积等于N。输入最多450组测试数据。数据以EOF结尾。输入一个整数N&#xff08;0 ≤ N ≤ 400)。输出…

asp.net mvc 地址栏传输信息报错:window.location.pathname

asp.net mvc 地址栏传输信息报错&#xff1a;window.location.pathname 前端cshtml代码内容 代码片. // 页面跳转 window.location.pathname /Home/Index?cc123;“/”应用程序中的服务器错误 从客户端(?)中检测到有潜在危险的 Request.Path 值。 如何解决 web.config中添…

区间覆盖全部类型及部分精选习题汇总详解(贪心策略)

内容如下&#xff1a; 1&#xff09;区间完全覆盖问题 问题描述&#xff1a;给定一个长度为m的区间&#xff0c;再给出n条线段的起点和终点&#xff08;注意这里是闭区间&#xff09;&#xff0c;求最少使用多少条线段可以将整个区间完全覆盖 样例&#xff1a; 区间长度8&#…

数据库提示:正在还原中,无法访问 应该怎么办?

Sql语句 restore database 数据库名 with recovery

数据库工具一段时间后打开报错:远程过程调用失败0x800706be

1.原因可能是安装vs时自带更高版本的sql server服务造成的&#xff0c;只需要卸载Microsoft SQL Server 2012 Express LocalDB或 Microsoft SQL Server 2012 LocalDB就行了 2.先安装vs工具&#xff0c;然后安装数据库工具

【POJ - 1328】Radar Installation(贪心+计算几何)安装雷达辐射岛屿

题干&#xff1a;Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so …

sql语句实现分页查询

2005及以上版本 -- 分页查询&#xff08;通用型&#xff09; select top pageSize * from (select row_number() over(order by sno asc) as rownumber,* from student) temp_row where rownumber>((pageIndex-1)*pageSize);2012及以上版本 select * from student orde…

【51nod-1289】大鱼吃小鱼

题干&#xff1a; 有N条鱼每条鱼的位置及大小均不同&#xff0c;他们沿着X轴游动&#xff0c;有的向左&#xff0c;有的向右。游动的速度是一样的&#xff0c;两条鱼相遇大鱼会吃掉小鱼。从左到右给出每条鱼的大小和游动的方向&#xff08;0表示向左&#xff0c;1表示向右&…

如何通过属性给实体赋值

获取实体属性 Type type family.GetType(); //family为实体对象 PropertyInfo[] infos type.GetProperties(); foreach (PropertyInfo info in infos){info.GetValue(family); //取值info.SetValue(bFamily, info.GetValue(family)); //赋值 }

【CF#801 A.】 Vicious Keyboard(字符串查找,水题)

题干&#xff1a;Tonio has a keyboard with only two letters, "V" and "K". One day, he has typed out a string s with only these two letters. He really likes it when the string "VK" appears, so he wishes to change at most one let…

关于ajax请求400问题解决

ajax请求&#xff1a;400 bad request 原因有两种&#xff1a; 参数不匹配&#xff0c;请求太长 如何解决 针对参数不匹配&#xff0c;只能一一对照 请求太长的话&#xff0c;api最好使用post方式请求&#xff0c;我遇到的问题就是post请求太长&#xff0c;这时候需要给参数…

【uva-673】 Parentheses Balance(括号匹配问题)

题干&#xff1a; You are given a string consisting of parentheses () and []. A string of this type is said to be correct:(a)if it is the empty string(b)if A and B are correct, AB is correct,(c)if A is correct, (A) and [A] is correct.Write a program that ta…

layui前端框架弹出框图标整理

1绿色对勾 2红色 3黄色问号 4黑色小锁 5红色哭脸 6绿色笑脸

【CF#757A】Gotta Catch Em' All!

题干&#xff1a;Bash wants to become a Pokemon master one day. Although he liked a lot of Pokemon, he has always been fascinated by Bulbasaur the most. Soon, things started getting serious and his fascination turned into an obsession. Since he is too young…

layui 折叠面板使用无效问题

静态折叠面板无法使用 解决方案&#xff1a;layui.js 引用位置应该放在距离layui.use临近的地方 动态设置折叠面板无法点击折叠展开 解决方案&#xff1a;动态加载完界面后&#xff0c;执行下面语句&#xff1a; layui.element.init();

【HDU - 1031 】Design T-Shirt(水题 排序)

题干&#xff1a;Soon after he decided to design a T-shirt for our Algorithm Board on Free-City BBS, XKA found that he was trapped by all kinds of suggestions from everyone on the board. It is indeed a mission-impossible to have everybody perfectly satisfie…

针对标签属性data-**的使用

在网站开发过程中&#xff0c;很多时候需要自定义一些标签属性&#xff0c;可以使用&#xff1a; 在html中&#xff1a; data-**"" 在js代码中取值&#xff1a; var **标签.data("**")

【HDU - 2203】 亲和串 (思维题,可选KMP)

题干&#xff1a;Problem Description人随着岁数的增长是越大越聪明还是越大越笨&#xff0c;这是一个值得全世界科学家思考的问题,同样的问题Eddy也一直在思考&#xff0c;因为他在很小的时候就知道亲和串如何判断了&#xff0c;但是发现&#xff0c;现在长大了却不知道怎么去…

【HDU - 4509】湫湫系列故事——减肥记II(合并区间模板 or 离散化标记 or 线段树)

题干&#xff1a;虽然制定了减肥食谱&#xff0c;但是湫湫显然克制不住吃货的本能&#xff0c;根本没有按照食谱行动&#xff01; 于是&#xff0c;结果显而易见… 但是没有什么能难倒高智商美女湫湫的&#xff0c;她决定另寻对策——吃没关系&#xff0c;咱吃进去再运动运动消…