1423:【例题2】种树
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 773 通过数: 236
【题目描述】
现在我们国家开展新农村建设,农村的住房建设纳入了统一规划,统一建设,政府要求每一住户门口种些树。门口路边的地区被分割成块,并被编号成1..N。每个部分为一个单位尺寸大小并最多可种一棵树。每个居民房子门前被指定了三个号码B,E,T。这三个数表示该居民想在B和E之间最少种T棵树。当然,B≤E,居民必须记住在指定区不能种多于区域地块数的树,所以T≤E-B+l。居民们想种树的各自区域可以交叉。你的任务是求出能满足所有要求的最少的树的数量,尽量较少政府的支出。
【输入】
第一行包含数据N,M,区域的个数(0<N≤30000),房子的数目(0<m≤5000);
下面的m行描述居民们的需要:B E T,0<B≤E≤30000,T≤E-B+1。
【输出】
输出第一行写有树的数目,下面的行包括所有树的位置,相邻两数之间用一个空格隔开。
【输入样例】
9 4 3 5 2 1 4 2 4 6 2 8 9 2
【输出样例】
5 3 4 6 8 9
#include <cstdio> #include <vector> #include <algorithm> struct Node { int start, end, num; Node(int s, int e, int h) : start(s), end(e), num(h) {} }; bool cmp(const Node& a, const Node& b) { return a.end < b.end; } std::vector<Node> nodes; // n: 区间数量,m:要求数量, ans:最少需要的多少棵树 int n, m, ans; bool flag[50005];//检测编号为i的单元是否已经种上了树 int main() { scanf("%d %d", &n, &m); for(int i = 0, s, e, h; i < m; i++) { scanf("%d %d %d", &s, &e, &h); nodes.push_back(Node(s, e, h)); } sort(nodes.begin(), nodes.end(), cmp); for(int i = 0; i < m; i++) { int tmp = 0;//表示当前已经种了多少棵树,判断tmp与需要种的数量是否相等 for(int j = nodes[i].start; j <= nodes[i].end; j++) { if(flag[j]) tmp++; if(tmp == nodes[i].num) break; } if(tmp < nodes[i].num) { for(int j = nodes[i].end; j >= nodes[i].start; j--) { if(!flag[j]) { flag[j] = true; tmp++;ans++; if(tmp == nodes[i].num) { break; } } } } } printf("%d", ans); }