image.png

image.png

문제 태그

아이디어

정답

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vll = vector<ll>;
using vpii = vector<pii>;

#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define F first
#define S second
#define pb push_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound

#ifndef ONLINE_JUDGE
template<typename A, typename B>
ostream& operator<<(ostream& os, const pair<A, B>& p) {
    return os << "{" << p.first << ", " << p.second << "}";
}
template<typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "[";
    for (size_t i = 0; i < v.size(); ++i) {
        os << v[i];
        if (i != v.size() - 1) os << ", ";
    }
    return os << "]";
}

#define debug(...) cerr << "[DEBUG] " << #__VA_ARGS__ << ": ", DBG(__VA_ARGS__)
template<typename T> void DBG(const T& v) { cerr << v << endl; }
template<typename T, typename... Args> void DBG(const T& v, const Args&... args) { cerr << v << ", "; DBG(args...); }
#else
#define debug(...)
#endif

const ll INF = 1e18;
const int MAX_K = 366; 

ll dp[MAX_K][MAX_K];
ll prev_min[MAX_K];

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    int t;
    cin >> t;
    while(t--) {
        int n, k;
        cin >> n >> k;

        vpii friends; 
        vi count_by_cap(k + 1, 0);
        
        for (int i = 1; i <= n; ++i) {
            int cap;
            cin >> cap;
            if (cap == 0) continue;

            if (count_by_cap[cap] < (k / cap) + 2) {
                friends.pb({i, cap});
                count_by_cap[cap]++;
            }
        }

        for(int c = 0; c <= k; ++c) {
            for(int v = 0; v <= k; ++v) {
                dp[c][v] = INF;
            }
        }
        dp[0][0] = 0;

        vector<pair<int, ll>> col_updates;
        col_updates.reserve(k + 1);

        for (auto& p : friends) {
            int idx = p.F;
            int cap = p.S;

            for (int c = 0; c <= k; ++c) {
                if (dp[c][0] != INF) prev_min[c] = dp[c][0];
                else prev_min[c] = INF;
            }
            for (int new_v = 1; new_v <= cap; ++new_v) {
                ll add_term = (ll)new_v * idx;
                int max_c = k - new_v;
                
                col_updates.clear();

                for (int c = 0; c <= max_c; ++c) {
                    if (prev_min[c] != INF) {
                        ll candidate = prev_min[c] + add_term;
                        if (candidate < dp[c + new_v][new_v]) {
                            col_updates.pb({c + new_v, candidate});
                        }
                    }
                }

                if (new_v < cap) {
                    for (int c = new_v; c <= k; ++c) {
                        if (dp[c][new_v] != INF) {
                            ll val = dp[c][new_v] - (ll)new_v * idx;
                            if (val < prev_min[c]) {
                                prev_min[c] = val;
                            }
                        }
                    }
                }

                for (auto& u : col_updates) {
                    if (u.S < dp[u.F][new_v]) {
                        dp[u.F][new_v] = u.S;
                    }
                }
            }
        }

        ll ans = 0;
        for (int c = 0; c <= k; ++c) {
            for (int v = 0; v <= c; ++v) {
                if (dp[c][v] != INF) {
                    ll current_happiness = (ll)(n + 1) * v - dp[c][v];
                    if (current_happiness > ans) ans = current_happiness;
                }
            }
        }
        cout << ans << "\\n";
    }
    
    return 0;
}