P1250 種樹
阿新 • • 發佈:2018-02-12
們的 結束 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 種樹