【题目描述】
文翁班上有N(1<=N<=500)N(1<=N<=500)个学生,编号1...N1...N。对于第i个学生他们需要在[Si,Ti][Si,Ti]时间段中做作业,且需要bibi支笔。可能在一个时刻有多个同学在写作业,但是他们不能同时使用一支笔。一个人写完作业后,他的笔就可以给别人用。
问,至少需要多少支不同的笔。
数据保证所有的si,ti各不同。
【输入】
输入的第一行包含N。
以下N行,每行描述了一个学生做作业情况,包含三个空格分隔的数si,ti和bi。 其中si和ti均为1…1000之间的整数,bi为1…10之间的整数。
【输出】
输出一个整数,至少需要的笔数量。
【样例输入】
3
4 10 1
8 13 3
2 6 2
【样例输出】
4
【提示】
样例解释
至少需要4支笔:从时间2开始,给3号学生用笔1和笔2。时间4开始给1号学生用笔3,从时间8开始给2号学生用笔1,2,4(笔1,2已经用完,可以再次使用)
分析:
听说学校要打欢乐赛,本蒟蒻也想去水一水。。。
结果不出所料,6道题只水过2道。。。
~唉~下面我们开始看这T1(打卡题)
算法一:
由于数据规模不大,直接暴力计算每个时间点需要的数量(多少个人覆盖这个时间点即他们需要的总和),打擂台
求出最大值。时间复杂度O(N*1000),~居然也能过~
算法二:
咦,这不是裸的线段树吗?线段树维护区间最大值,直接水过去
代码:
楼主的丑陋线段树:
#include<bits/stdc++.h>
using namespace std;
#define lc (p<<1)
#define rc (p<<1|1)
const int N=510;
int n,d[1100],mx,a[100010];
inline int read(){
int x=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return x;
}
struct node{
int l,r,lazy;
long long ans;
}T[100010*4];
void pushnow(long long p,long long v){
T[p].ans+=v;
T[p].lazy+=v;
}
void pushdown(long long p){
if(T[p].lazy){
pushnow(lc,T[p].lazy);
pushnow(rc,T[p].lazy);
T[p].lazy=0;
}
}
void pushup(long long p){
T[p].ans=max(T[lc].ans,T[rc].ans);
}
void build(long long p,long long l,long long r){
T[p].l=l;
T[p].r=r;
if(l==r){
T[p].ans=a[l];
T[p].lazy=0;
return ;
}
long long mid=(l+r)>>1;
build(lc,l,mid);
build(rc,mid+1,r);
pushup(p);
}
void update(long long p,long long ql,long long qr,long long v){
if(ql<=T[p].l&&T[p].r<=qr){
pushnow(p,v);
return ;
}
long long mid=(T[p].l+T[p].r)>>1;
pushdown(p);
if(ql<=mid)
update(lc,ql,qr,v);
if(qr>mid)
update(rc,ql,qr,v);
pushup(p);
}
long long query(long long p,long long ql,long qr){//区间求和
if(ql<=T[p].l&&qr>=T[p].r)
return T[p].ans;
long long mid=(T[p].l+T[p].r)>>1;
pushdown(p);
long long ans=0;
if(ql<=mid)
ans=max(ans,query(lc,ql,qr));
if(qr>mid)
ans=max(ans,query(rc,ql,qr));
pushup(p);
return ans;
}
int main(){
n=read();
build(1,1,1010);
while(n--){
int s=read(),t=read(),k=read();
mx=max(mx,t);
update(1,s,t,k);
}
long long r=query(1,1,mx);
cout<<r;
return 0;
}