做贪心时,题目给出多个区间,要求找出多少区间重叠,一般可以转化成数组,在区间内,数组所指的位置加1,例如区间(a,b),那么就给(s[a], s[b])区间内的数组元素加1,然后最后寻找数组最大值,即为区间重叠的个数。
典型问题 NYOJ 168 房间安排,HDOJ 1050 Move tables
2010年上海世界博览会(Expo2010),是第41届世界博览会。于2010年5月1日至10月31日期间,在中国上海市举行。本次世博会也是由中国举办的首届世界博览会。上海世博会以“城市,让生活更美好”(Better City,Better Life)为主题,将充分探索21世纪城市生活。
这次世博会总投资达450亿人民币,创造了世界博览会史上的最大规模记录。吸引200个国家和国际组织参展。预计有7000万人次的参观者。
为了更好地接待在这期间来自世界各地的参观者,如何合理安排各宾馆的住房问题提到了日程。组委会已接到了大量的客户住宿定单,每张定单的内容包括要住宿的房间数,开始住宿时间和要住的天数。为了便于整个城市各宾馆的管理,组委会希望对这些定单进行安排,目的是用尽可能少的房间来满足这些定单,以便空出更多的房间用于安排流动游客。
组委会请求DR.Kong来完成这个任务,对这些定单进行合理安排,使得满足这些定单要求的房间数最少。
假设:某个定单上的游客一旦被安排到某房间,在他预定住宿的期间内是不换房间的。为了简化描述,定单上的开始住宿时间为距离现在的第几天。例如,定单为(10,30,5)表示游客要求使用10个房间,第30天开始连住5天。
1 3 3 10 4 4 9 3 3 12 6
7
代码如下
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
int m, n, a, b, c, i, j, s[200];
scanf("%d",&n);
while(n--)
{
memset(s,0,sizeof(s));
scanf("%d",&m);
for(i = 0; i < m; i++)
{
scanf("%d%d%d",&a,&b,&c);
for(j = b; j < b + c; j++)
s[j] += a;
}
int max = s[0];
for(i = 1; i < 200; i++)
if(max < s[i])
max = s[i];
printf("%d\n",max);
}
return 0;
}
找出需要多少个房间,用一个数组表示天数,每次给出数据,就对天数加1,最求看哪天入住的人最多,就需要多少房间数。就相当于找入住天数区间重叠的最大值。
3 4 10 20 30 40 50 60 70 80 2 1 3 2 200 3 10 100 20 80 30 50
10 20 30
代码如下
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int main()
{
int m, n, i, j, a, b, sum, s[210];
scanf("%d",&n);
while(n--)
{
memset(s, 0, sizeof(s));
scanf("%d",&m);
for(i = 0; i < m; i++)
{
scanf("%d%d",&a,&b);
if(a > b)
{
int t;
t = a;
a = b;
b = t;
}
if(a % 2) a = (a + 1) / 2;
else a /= 2;
if(b % 2) b = (b + 1) / 2;
else b /= 2;
for(j = a ; j <= b ; j++)
s[j]++;
}
sort(s,s + 210);
printf("%d\n",s[209] * 10);
}
return 0;
}
已知有400个房间,但是走廊的长度为200,每次移动的距离为一个区间,以走廊为一个数组,每次移动时区间内数组加一,最后看数组中哪个数最大,即为要分开移动的最少的桌子的数目,乘以10就为最小的时间。
两个题都是换了一种思路,做这两个题时,都没有想到,所以总结下来。希望下次能想到!!!!