"JSOI2015" matryoshka

"JSOI2015" matryoshka

Portal

Consider greedy.

First, we assume that all sets of nesting dolls are not each other.

We then consider merging two sets of baby \ (i \) , \ (j \) Suppose we \ (i \) set to \ (j \) to go inside, then you can reduce \ (b_j \ times out_i \) of spend.

We have a strategy that is greedy of all sets her press (b \) \ descending order, then each find a \ (out \) maximum it sets.

So we can prove the correctness:

For four doll \ (I, J, K, L \) , assuming \ (b_i> b_j, out_k> out_l \) and to ensure that \ (i, j \) can be set \ (K, L \) ,

So we only need to license \ (b_i \ Times out_k + b_j \ Times and OUT_L \ GE b_i \ Times and OUT_L + b_j \ Times out_k \) , based on the assumption that this formula is clearly established.

Then we can just follow the greedy strategy.

Specifically, it is to use a multisetmaintenance all \ (out \) , then press \ (b \) sort, each time multisetinside lower_boundone of the biggest \ (out \) and then lose the corresponding price.

Of particular note: if \ (IN_I = out_j \) , so \ (i \) is not set \ (j \) is.

Reference Code:

#include <algorithm>
#include <cstdio>
#include <set>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
    s = 0; int f = 0; char c = getchar();
    while ('0' > c || c > '9') f |= c == '-', c = getchar();
    while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
    s = f ? -s : s;
}
 
typedef long long LL;
const int _ = 2e5 + 5;
 
int n; struct node { int in, out, b; } t[_];
inline bool cmp(const node& x, const node& y) { return x.b > y.b; }
 
multiset < int > s;
multiset < int > ::iterator it;
 
int main() {
#ifndef ONLINE_JUDGE
    file("cpp");
#endif
    read(n);
    LL ans = 0;
    for (rg int i = 1; i <= n; ++i) {
        read(t[i].out), read(t[i].in), read(t[i].b);
        ans += 1ll * t[i].b * t[i].in, s.insert(t[i].out);
    }
    sort(t + 1, t + n + 1, cmp);
    for (rg int i = 1; i <= n; ++i) {
        it = s.lower_bound(t[i].in);
        if (it != s.begin()) ans -= 1ll * t[i].b * (*--it), s.erase(it);
    }
    printf("%lld\n", ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/zsbzsb/p/12301962.html