51,716
社区成员




难点考虑当我们在考虑某一天时,总是纠结选价格低的还是选保质期短的,因为这会影响我们后面的选择。
如果我们无需关心后面,只着重与眼前,那么对于可以吃的巧克力,我们一定会选择最便宜的那种,这一定是正确的。
那么思考,什么时候是不需要考虑后面的天数呢 ?没错,我们倒着来考虑,先考虑最后一天能吃哪些巧克力,然后在所有能吃的巧克力中选一个最便宜的,接下来考虑倒数第二天。因为最后一天能吃的巧克力,在倒数第二天一定也能吃。 而且此时我们有可能可以添加一些巧克力,它在最后一天不能吃,而在倒数第二天能吃,显然从一堆巧克力中每次都要取出最小的,且需要动态维护增加和删除,那么我们需要想到优先队列。
将巧克力按保质期排序,然后从最后一天往第一天倒着考虑,每次将可以吃的巧克力放入优先队列中,如果发现某一天队列为空,说明无解。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> PII;
#define pb(s) push_back(s);
#define SZ(s) ((int)s.size());
#define ms(s,x) memset(s, x, sizeof(s))
#define all(s) s.begin(),s.end()
const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
const int N = 200010;
int x, n;
void solve()
{
cin >> x >> n;
std::vector<pair<int, PII>> v(n);
std::vector<int> cnt(n), c(n);
for (int i = 0; i < n; ++i) {
int a, b;
cin >> a >> b >> c[i];
v[i] = {b, {a, i}};
}
sort(all(v));
priority_queue<PII, vector<PII>, greater<PII> >q;
int l = n - 1;
LL ans = 0;
//倒着考虑
for (int i = x; i >= 1; i--) {
while (l >= 0 && v[l].first >= i) {
q.push(v[l].second);
l--;
}
if (q.size() == 0) {
cout << -1 << '\n';
return;
}
PII d = q.top();
ans += d.first;
cnt[d.second]++;
if (cnt[d.second] == c[d.second]) q.pop();
}
cout << ans << '\n';
}
int main()
{
ios_base :: sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int t = 1;
while (t--)
{
solve();
}
return 0;
}