HENAU

目录

E - 最大子段和

F - 活动安排问题

G - 线段


E - 最大子段和

N个整数组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的连续子段和的最大值。当所给的整数均为负数时和为0。

例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。

Input

第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)

Output

输出最大子段和。

Sample

InputcopyOutputcopy
6
-2
11
-4
13
-5
-2
import java.util.Scanner;

public class Main{

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin=new Scanner(System.in);
		int n=cin.nextInt();
		
		long ans=0,res=0;
		while(n-->0) {
			int x=cin.nextInt();
			ans+=x;
			if(ans<0)ans=0;
			res=Math.max(ans,res);
		}
		
		System.out.println(res);
	}

}

F - 活动安排问题

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

Input

第一行一个正整数n代表活动的个数。 之后n行每行两个数s,t,分别为开始/结束时间。 其中n<=10000,0<=t1 <1e9。

Output

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

Sample

InputcopyOutputcopy
3
1 2
3 4
2 9

思路:要想所使用的教室最少,那么每个教室的使用次数应该尽可能的多,也就是说,每个教室的活动个数都是最大不相交子区间

import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

class p{
	int s,t;
}
public class Main{

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin=new Scanner(System.in);
		int n=cin.nextInt();
		
		p a[]=new p[n];
		
		for(int i=0;i<n;i++) {
			a[i]=new p();
			a[i].s=cin.nextInt();
			a[i].t=cin.nextInt();
		}
		
		Arrays.sort(a,(o1,o2)->o1.s-o2.s);
		
		//优先队列用来动态模拟教室的数量
		PriorityQueue<Integer>q=new PriorityQueue<>();
		for(int i=0;i<n;i++) {
			if(q.isEmpty())q.add(a[i].t);
			else {
				if(a[i].s<q.peek())q.add(a[i].t);
				else {
					q.poll();
					q.add(a[i].t);
				}
			}
		}
		
		System.out.println(q.size());
	}

}

G - 线段

 

数轴上有 nn 条线段,选取其中 kk 条线段使得这 kk 条线段两两没有重合部分,问 kk 最大为多少。

输入格式

第一行为一个正整数 nn;

在接下来的 nn 行中,每行有 22 个数 a_i, b_iai​,bi​,描述每条线段。

输出格式

输出一个整数,为 kk 的最大值。

样例

InputcopyOutputcopy
3
0 2
2 4
1 3
2

数据范围与提示

对于 20\%20% 的数据,n \leq 10n≤10;

对于 50\%50% 的数据,n \leq 10^3n≤103;

对于 70\%70% 的数据,n \leq 10^5n≤105;

对于 100\%100% 的数据,n \leq 10^6,n≤106, 0 \leq a_i \lt b_i \leq 10^60≤ai​<bi​≤106。

思路:由题意可得我们求得是最大不相交区间,那么我们可以按照右端点进行排序,然后遍历一遍即可。按右端点排序是因为我们要保证一个区间能尽早结束,才能加入下一个区间,这就是贪心的思想。

#include<bits/stdc++.h>
using namespace std;

pair<int,int>a[1000010];
bool cmp(const pair<int,int>&a,const pair<int,int>&b)
{
	return a.second<b.second;
}
int main(){
	int n;
	scanf("%d",&n);
	
	for(int i=0;i<n;i++){
		scanf("%d%d",&a[i].first,&a[i].second);
	}
	
	sort(a,a+n,cmp);
	
	int cnt=1,ed=a[0].second;
	for(int i=1;i<n;i++){
		if(a[i].first>=ed){
			cnt++;
			ed=a[i].second;
		}
	}
	
	printf("%d\n",cnt);
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值