1. 程式人生 > >LOJ#10001 種樹(貪心)

LOJ#10001 種樹(貪心)

題目連結

題目描述

某條街被劃為 n 條路段,這 n 條路段依次編號為 1…n。每個路段最多可以種一棵樹。現在居民們給出了 h 組建議,每組建議包含三個整數 b,e,t 表示居民希望在路段 b 到 e之間至少要種 t 棵樹。這些建議所給路段的區間可以交叉。請問:如果要滿足所有居民的建議,至少要種多少棵樹。

輸入格式

第一行為 n,表示路段數。

第二行為 h,表示建議數。

下面 h 行描述一條建議:b,e,t 用一個空格分隔。

輸出格式

輸出只有一個數,為滿足所有居民的建議,所需要種樹的最少數量。

樣例

樣例輸入

9
4
1 4 2
4 6 2
8 9 2
3 5 2

樣例輸出

5

資料範圍與提示

30%的資料滿足 0<n≤1000,0<h≤500;

100%的資料滿足 0<n≤3×10^4,h≤5000,0<b≤e≤3×10^4,t≤e−b+1。

區間問題。按右端點的升序排序,將樹儘可能的往右端點種

AC程式碼:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<vector>
#include<stack>
using namespace std;
struct node
{
	int l,r,num;
	friend bool operator <(node a,node b)
	{
	   return a.r<b.r;
	}
}sugg[5001];//suggestion
int main()
{
	int n,h,ans=0;
	bool isplan[30001];//is planted
	memset(isplan,0,sizeof(isplan));
	cin>>n>>h;
	for(int i=1;i<=h;i++) 
	cin>>sugg[i].l>>sugg[i].r>>sugg[i].num;
	sort(sugg+1,sugg+h+1);
	
	for(int i=1;i<=h;i++)
	{
		int t=0;//當前建議已種樹數目 
		for(int j=sugg[i].r;j>=sugg[i].l;j--) t+=isplan[j];
		for(int j=sugg[i].r;j>=sugg[i].l&&t<sugg[i].num;j--) 
			if(!isplan[j]) isplan[j]=1,ans++,t++;
	}
	cout<<ans;
}