题目描述
某条街被划为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
数据范围与提示
0<≤3×1040<n≤3×104
0<ℎ≤50000<h≤5000
0≤3×104,≤−+10<b≤e≤3×104,t≤e−b+1
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
struct Suggestion
{
int b, e, t;
};
bool compare(const Suggestion &a, const Suggestion &b)
{
return a.e < b.e;
}
int minTreesToPlant(int n, int h, vector<Suggestion> &suggestions)
{
vector<int> trees(n + 1, 0); // 使用一个数组来记录每个路段是否种树,初始为0
sort(suggestions.begin(), suggestions.end(), compare); // 按结束路段排序
int total_trees = 0;
for (const auto &suggestion : suggestions)
{
int b = suggestion.b, e = suggestion.e, t = suggestion.t;
// 计算当前区间内已经种了多少棵树
int current_trees = 0;
for (int i = b; i <= e; i++)
{
current_trees += trees[i];
}
// 需要补种的树的数量
int needed_trees = t - current_trees;
// 从区间末尾向前补种树
for (int i = e; i >= b && needed_trees > 0; i--)
{
if (trees[i] == 0)
{
trees[i] = 1;
total_trees++;
needed_trees--;
}
}
}
return total_trees;
}
int main()
{
int n, h;
cin >> n >> h;
vector<Suggestion> suggestions(h);
for (int i = 0; i < h; i++)
{
cin >> suggestions[i].b >> suggestions[i].e >> suggestions[i].t;
}
cout << minTreesToPlant(n, h, suggestions) << endl;
return 0;
}