貪心+線段樹 [USACO09FEB]Fair Shuttle G(洛谷 P1607)

[USACO09FEB]Fair Shuttle G

題目描述

Although Farmer John has no problems walking around the fair to collect prizes or see the shows, his cows are not in such good shape; a full day of walking around the fair leaves them exhausted. To help them enjoy the fair, FJ has arranged for a shuttle truck to take the cows from place to place in the fairgrounds.

FJ couldn’t afford a really great shuttle, so the shuttle he rented traverses its route only once (!) and makes N (1 <= N <= 20,000) stops (conveniently numbered 1…N) along its path. A total of K (1 <= K <= 50,000) groups of cows conveniently numbered 1…K wish to use the shuttle, each of the M_i (1 <= M_i <= N) cows in group i wanting to ride from one stop S_i (1 <= S_i < E_i) to another stop E_i (S_i < E_i <= N) farther along the route.

The shuttle might not be able to pick up an entire group of cows (since it has limited capacity) but can pick up partial groups as appropriate.

Given the capacity C (1 <= C <= 100) of the shuttle truck and the descriptions of the groups of cows that want to visit various sites at the fair, determine the maximum number of cows that can ride the shuttle during the fair.

逛逛集市,兌兌獎品,看看節目對農夫約翰來說不算什麼,可是他的奶牛們非常缺乏鍛鍊——如果要逛完一整天的集市,他們一定會筋疲力盡的。所以爲了讓奶牛們也能愉快地逛集市,約翰準備讓奶牛們在集市上以車代步。但是,約翰木有錢,他租來的班車只能在集市上沿直線跑一次,而且只能停靠N(1 ≤N≤20000)個地點(所有地點都以1到N之間的一個數字來表示)。現在奶牛們分成K(1≤K≤50000)個小組,第i 組有Mi(1 ≤Mi≤N)頭奶牛,他們希望從Si跑到Ti(1 ≤Si<Ti≤N)。

由於班車容量有限,可能載不下所有想乘車的奶牛們,此時也允許小裏的一部分奶牛分開乘坐班車。約翰經過調查得知班車的容量是C(1≤C≤100),請你幫助約翰計劃一個儘可能滿足更多奶牛願望的方案。

輸入格式

【輸入】

第一行:包括三個整數:K,N和C,彼此用空格隔開。

第二行到K+1行:在第i+1行,將會告訴你第i組奶牛的信息:Si,Ei和Mi,彼

此用空格隔開。

輸出格式

【輸出】

第一行:可以坐班車的奶牛的最大頭數。


首先要想到以右邊界把區間進行排序,右邊界小的排在前面;

然後貪心的根據當前區間 [l,r] 的最大人數上人,只要保證總人數不超過限制,然後區間 [l,r-1] 加上上的人數,繼續維護最大值;

這個區間最大值,區間修改顯然線段樹是一個很棒的方式;

代碼:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,LL>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=50100;
const int M=400100;
const int mod=1e9+7;
int k,n,c;
struct Nod{
	int s,e,m;
}d[N];
bool cmp(Nod p,Nod q){
	if(p.e==q.e) return p.s<q.s;
	return p.e<q.e;
}
struct Node{
	int l,r,mx,lt;
}tr[N*4];
void build(int l,int r,int k){
	tr[k].l=l,tr[k].r=r;
	if(l==r) return;
	int d=(l+r)>>1;
	build(l,d,ls);
	build(d+1,r,rs);
}
void pd(int k){
	if(tr[k].lt){
		tr[ls].lt+=tr[k].lt,tr[rs].lt+=tr[k].lt;
		tr[ls].mx+=tr[k].lt,tr[rs].mx+=tr[k].lt;
	}
	tr[k].lt=0;
}
int query(int l,int r,int k){
	if(tr[k].l>=l&&tr[k].r<=r) return tr[k].mx;
	pd(k);
	int d=(tr[k].l+tr[k].r)>>1;
	int mmax=0;
	if(l<=d) mmax=max(mmax,query(l,r,ls));
	if(r>d) mmax=max(mmax,query(l,r,rs));
	return mmax;
}
void add(int l,int r,int w,int k){
	if(tr[k].l>=l&&tr[k].r<=r){
		tr[k].mx+=w;
		tr[k].lt+=w;
		return;
	}
	pd(k);
	int d=(tr[k].l+tr[k].r)>>1;
	if(l<=d) add(l,r,w,ls);
	if(r>d) add(l,r,w,rs);
	tr[k].mx=max(tr[ls].mx,tr[rs].mx);
}
int main(){
	scanf("%d%d%d",&k,&n,&c);
	build(1,n,1); 
	for(int i=1;i<=k;i++) scanf("%d%d%d",&d[i].s,&d[i].e,&d[i].m);
	sort(d+1,d+k+1,cmp);
	int ans=0;
	for(int i=1;i<=k;i++){
		int mmax=query(d[i].s,d[i].e,1);
		if(mmax+d[i].m>c) add(d[i].s,d[i].e-1,c-mmax,1),ans+=c-mmax;
		else add(d[i].s,d[i].e-1,d[i].m,1),ans+=d[i].m;
	} 
	printf("%d\n",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章