Вариация проблем с укладкой коробки

Некоторое время я пытался решить следующую проблему конкурса:

Вы хотите построить башню как можно выше из N кирпичей. Каждый кирпич представляет собой кубоид с квадратным дном, а башня представляет собой набор кирпичей, сложенных друг на друге. Чтобы башня не стала нестабильной, каждый кирпич должен быть строго шире кирпича сверху. Поэтому башня построена из самых широких кирпичей в нижней части и самой узкой в ​​верхней части. По эстетическим соображениям каждый кирпич должен быть по крайней мере таким же высоким, как тот кирпич, на котором он лежит.

Нам дано количество кирпичей N, а также их ширина и высота. Мы хотим выяснить максимальную высоту.

После окончания конкурса были представлены следующие два решения:

Решение 1:

#include<bits/stdc++.h>

using namespace std;

#define rep(i,a,b) for(int i = a; i<int(b);++i)
#define all(v) v.begin(),v.end()

typedef long long ll;
typedef vector<ll> vi;
typedef pair<ll,ll> pii;

struct Tree {
    typedef ll T;
    const T LOW = -1234567890;
    T f(T a, T b) { return max(a, b); }

    int n;
    vi s;
    Tree() {}
    Tree(int m, T def=0) { init(m, def); }
    void init(int m, T def) {
        n = 1; while (n < m) n *= 2;
        s.assign(n + m, def);
        s.resize(2 * n, LOW);
        for (int i = n; i --> 1; )
            s[i] = f(s[i * 2], s[i*2 + 1]);
    }
    void update(int pos, T val) {
        pos += n;
        s[pos] = val;
        for (pos /= 2; pos >= 1; pos /= 2)
            s[pos] = f(s[pos * 2], s[pos * 2 + 1]);
    }
    T query(int l, int r) { return que(1, l, r, 0, n); }
    T que(int pos, int l, int r, int lo, int hi) {
        if (r <= lo || hi <= l) return LOW;
        if (l <= lo && hi <= r) return s[pos];
        int m = (lo + hi) / 2;
        return f(que(2 * pos, l, r, lo, m),
                que(2 * pos + 1, l, r, m, hi));
    } 
};

int main() { 
    cin.sync_with_stdio(false);
    ll n; cin>>n;
    map<ll,ll> heights;
    vector<pii> v(n);
    rep(i,0,n){
        cin>>v[i].first>>v[i].second;
        heights[v[i].second] = 1;
    }
    ll ind = 0;
    for(auto e:heights) heights[e.first] = ind++;

    sort(all(v));
    reverse(all(v));

    Tree st(n);
    rep(i,0,v.size())
        if (i == 0 || v[i] != v[i-1])
        st.update(heights[v[i].second],st.query(0,heights[v[i].second]+1) + v[i].second);
    cout<<st.query(0,n)<<endl;
}

Решение 2:

#include <bits/stdc++.h>
using namespace std;

#define rep(i, from, to) for (int i = from; i < (to); ++i)
#define trav(a, x) for (auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

int main() {
    cin.sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    int N;
    cin >> N;
    vector<pii> bricks;
    rep(i,0,N) {
        int w, h;
        cin >> w >> h;
        bricks.emplace_back(w, h);
    }
    sort(all(bricks));
    // width strictly increasing, height weakly decreasing
    map<int, ll> answers;
    answers[INT_MAX] = 0;
    pii lastbr = {-1, -1};
    trav(br, bricks) {
        if (br == lastbr) continue;
        lastbr = br;
        int h = br.second;
        auto it = answers.lower_bound(h);
        assert(it != answers.end());
        ll nh = it->second + h;
        if (it->first == h) {
            it->second = nh;
        } else {
            it = answers.insert(it, make_pair(h, nh));
        }
        while (it != answers.begin()) {
            --it;
            if (it->second <= nh) it = answers.erase(it);
            else break;
        }
    }

    ll res = 0;
    trav(pa, answers) res = max(res, pa.second);
    cout << res << endl;

    exit(0);
}

Я довольно новичок в соревнованиях по программированию и C++. Если бы кто-нибудь мог объяснить мне алгоритм по-новому, я был бы благодарен. Я в основном написал код на Java, поэтому, если кто-то захочет представить пример или объяснение в коде, я бы предпочел java. Заранее спасибо!

Постановка задачи полностью с примером ввода / вывода: https://translate.google.se/translate?hl=sv&sl=sv&tl=en&u=https%3A%2F%2Fpo.kattis.com%2Fproblems%2Ftornbygge

Еще одна проблема, которая, как мне показалось, выглядела аналогично: башня ящиков (укладка кубов)

Проблема с оригинальной коробкой https://www.geeksforgeeks.org/dynamic-programming-set-21-box-stacking-problem/

0 ответов

Другие вопросы по тегам