Submission #672354

#TimeUsernameProblemLanguageResultExecution timeMemory
672354senagoKnapsack (NOI18_knapsack)C++17
100 / 100
134 ms2928 KiB
#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <vector>

struct item {
    size_t weight = 0;
    size_t value = 0;
    size_t count = 0;
};

std::vector<item> filter_items(const std::vector<item>& items, size_t capacity) noexcept {
    std::vector<item> filtered;
    filtered.reserve(items.size());

    std::unordered_map<size_t, size_t> counts;
    for (const item& item : items) {
        if (counts[item.weight] * item.weight > capacity) {
            continue;
        }
        counts[item.weight] += item.count;
        filtered.push_back(item);
    }

    return filtered;
}

std::vector<item> prepare_items(std::vector<item>& items, size_t capacity) noexcept {
    const auto cmp = [](const item& lhs, const item& rhs) {
        if (lhs.weight == rhs.weight) {
            return lhs.value > rhs.value;
        }
        return lhs.weight < rhs.weight;
    };
    std::sort(items.begin(), items.end(), cmp);
    return filter_items(items, capacity);
}

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    size_t amount_of_types = 0, capacity = 0;
    std::cin >> capacity >> amount_of_types;

    size_t min_weight = std::numeric_limits<size_t>::max();
    std::vector<item> items(amount_of_types);
    for (size_t i = 0; i < amount_of_types; ++i) {
        size_t weight = 0, value = 0, count = 0;
        std::cin >> value >> weight >> count;
        items[i] = {weight, value, count};
        if (weight < min_weight) {
            min_weight = weight;
        }
    }
    items = prepare_items(items, capacity);
    size_t max = 0;
    std::vector<size_t> dp(capacity + 1, 0);
    for (const auto& item : items) {
        for (size_t cap = capacity; cap >= min_weight; --cap) {
            size_t curr_weight = 0, curr_value = 0;
            const size_t limit = std::min(item.count, cap / item.weight);
            for (size_t count = 1; count <= limit; ++count) {
                curr_weight += item.weight, curr_value += item.value;
                const size_t alt = dp[cap - curr_weight] + curr_value;
                dp[cap] = std::max(dp[cap], alt);
            }
            max = std::max(max, dp[cap]);
        }
    }

    std::cout << max << '\n';

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...