1. 程式人生 > >P1250 種樹

P1250 種樹

們的 結束 ron sta i++ print 單位 using 交叉

題目描述

一條街的一邊有幾座房子。因為環保原因居民想要在路邊種些樹。路邊的地區被分割成塊,並被編號成1..N。每個部分為一個單位尺寸大小並最多可種一棵樹。每個居民想在門前種些樹並指定了三個號碼B,E,T。這三個數表示該居民想在B和E之間最少種T棵樹。當然,B≤E,居民必須記住在指定區不能種多於區域地塊數的樹,所以T≤E-B+l。居民們想種樹的各自區域可以交叉。你的任務是求出能滿足所有要求的最少的樹的數量。

寫一個程序完成以下工作:

輸入輸出格式

輸入格式:

第一行包含數據N,區域的個數(0<N≤30000);

第二行包含H,房子的數目(0<H≤5000);

下面的H行描述居民們的需要:B E T,0<B≤E≤30000,T≤E-B+1。

輸出格式:

輸出文件只有一行寫有樹的數目

輸入輸出樣例

輸入樣例#1: 復制
9
4
1 4 2
4 6 2
8 9 2
3 5 2
輸出樣例#1: 復制
5


相信肯定有人一上來就差分約束,其實這題可以貪心(卡常卡卡就過了)
按結束時間排序,區間內進行貪心,詳見代碼。
AC代碼如下:
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=5000+5;
const int M=30000+5;
struct p{
    int start,end,need;
    bool operator
<(const p &a) const{ if(a.end==end) return start<a.start; return end<a.end; } }e[N]; bool use[M]; int now,n,h,ans; int main() { scanf("%d%d",&n,&h); for(int i=1;i<=h;i++) scanf("%d%d%d",&e[i].start,&e[i].end,&e[i].need); sort(e+1,e+h+1
); for(int i=1;i<=h;i++) { now=0; for(int j=e[i].start;j<=e[i].end;j++) now+=use[j]; for(int j=e[i].end;now<e[i].need&&j>=e[i].start;j--) if(!use[j]) use[j]=1,now++,ans++; } printf("%d",ans); return 0; }

P1250 種樹