贪心小结

1. 活动安排问题

X轴上有N条线段,每条线段有1个起点S和终点E。最多能够选出多少条互不重叠的线段。(注:起点或终点重叠,不算重叠)。

例如:[1 5][2 3][3 6],可以选[2 3][3 6],这2条线段互不重叠。可以选出多少个活动。

输入

第1行:1个数N,线段的数量(2 <= N <= 10000)
第2 - N + 1行:每行2个数,线段的起点和终点(-10^9 <= S,E <= 10^9)

输出

输出最多可以选择的线段数量。

输入示例

3
1 5
2 3
3 6

输出示例
2
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define M 10005 
struct nod{
	int s;//起点
	int e;//终点
}a[M];
int cmp(nod a,nod b){
	return a.e<b.e;
}
int main()
{
	int n;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			scanf("%d%d",&a[i].s,&a[i].e);
		}
		sort(a,a+n,cmp);
		int ans=1;
	    int temp=a[0].e;
	    for(int i=1;i<n;i++){
	    	if(temp<=a[i].s){
	    		ans++;
	    		temp=a[i].e;
			}
		}
	
		printf("%d\n",ans);
	}
	return 0;
} 

2. 活动安排之二

有若干个活动,第i个开始时间和结束时间是[Si,fi),同一个教室安排的活动之间不能交叠,求要安排所有活动,最少需要几个教室? 

开始时间和结束时间分别排序,画图可得,当开始时间小于结束时间就需要另外开一间教室,教室的数量sum++;当开始间大于当前的结束,就跟上一个活动不冲突,不用另外安排教室。结束时间的指针就要往后跟新一个。

输入

第一行一个正整数n (n <= 10000)代表活动的个数。
第二行到第(n + 1)行包含n个开始时间和结束时间。
开始时间严格小于结束时间,并且时间都是非负整数,小于1000000000

输出

一行包含一个整数表示最少教室的个数。

输入示例

3
1 2
3 4
2 9
输出示例
2
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define inf 0x3f3f3f3f
const int N = 10005;

int s[N],d[N];
 
int main()
{
	int n;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			scanf("%d%d",&s[i],&d[i]);
		}
		sort(s,s+n);
		sort(d,d+n);
		int sum=0,max=0,i,j=0;
		for(i=0;i<n;i++){
			if(s[i]<d[j]){
				sum++;
				if(sum>max){
					max=sum;
				}
			}
			else
				j++;
		}
		printf("%d\n",max);
	}
	return 0;
} 

3. 任务执行顺序

有N个任务需要执行,第i个任务计算时占R[i]个空间,而后会释放一部分,最后储存计算结果需要占据O[i]个空间(O[i] < R[i])。

例如:执行需要5个空间,最后储存需要2个空间。给出N个任务执行和存储所需的空间,问执行所有任务最少需要多少空间。

多个任务是按顺序依次执行的,按照释放空间先非递减排序,遍历看释放空间的改变情况。释放空间free执行完意向任务所释放的空间,所以初始化为0,占有空间总数sum为0 。如果free大于下一个计算r[i]的话,就跟新free的值,sum不做改变。否则,就sum=sum+r[i]-free;就是新的sum值free更新为o[i]。

输入

 

第1行:1个数N,表示任务的数量。(2 <= N <= 100000)
第2 - N + 1行:每行2个数R[i]和O[i],分别为执行所需的空间和存储所需的空间。(1 <= O[i] < R[i] <= 10000)

输出

输出执行所有任务所需要的最少空间。

输入示例

20
14 1
2 1
11 3
20 4
7 5
6 5
20 7
19 8
9 4
20 10
18 11
12 6
13 12
14 9
15 2
16 15
17 15
19 13
20 2
20 1
输出示例
135
#include<stdio.h>
#include<algorithm>
using namespace std; 
struct node{
	int r;
	int o;
}a[100010];

int cmp(node x,node y){
	return x.o>y.o;
}
int main() 
{
	int n;
	long long sum=0;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&a[i].r,&a[i].o);
		a[i].o=a[i].r-a[i].o;
		//sum+=a[i].o;
	}
	sort(a,a+n,cmp);
	int free=0;
	for(int i=0;i<n;i++){
		if(free>=a[i].r){
			free=free-a[i].r+a[i].o;
		}
		else{
			sum+=a[i].r-free;
			free=a[i].o;
		}
	} 
	printf("%lld\n",sum);
	return 0;
}

4. 独木舟问题,考虑最轻的和最重的,两头一起遍历,一定要遍历到r==l;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值