# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1252411 | haiphong5g0 | 축제 (IOI25_festival) | C++20 | 0 ms | 0 KiB |
//#include "souvenirs.h"
#include <bits/stdc++.h>
#define task "TEST"
#define task2 "A"
#define pl pair<ll, ll>
#define pf push_front
#define pb push_back
#define pob pop_back
#define pof pop_front
#define mp make_pair
#define fi first
#define se second
#define FOR(i, a, b, c) for (int i=a; i<=b; i+=c)
#define FORE(i, a, b, c) for (int i=a; i>=b; i+=c)
using namespace std;
using ll = long long;
using Knowledge = pair<vector<int>, ll>;
using ull = unsigned long long;
const int Mod = 998244353;
const int maxn = 1e3;
const ll Inf = 1e16;
ll n, a, s;
vector<int> P, T;
struct Coupon {
ll p;
ll pos;
bool operator < (Coupon other) const {
return p < other.p;
};
};
vector<Coupon> C[5];
ll Fix(ll& i, ll& j, ll& k, ll& h, ll pos, ll add) {
ll v;
if (pos == 1) i += add, v = i;
if (pos == 2) j += add, v = j;
if (pos == 3) k += add, v = k;
if (pos == 4) h += add, v = h;
return v;
}
vector<int> max_coupons(int s, vector<int> P, vector<int> T) {
a = s; FOR(i, 0, P.size()-1, 1) C[T[i]].pb({P[i], i});
FOR(i, 1, 4, 1) if (C[i].size()) sort(C[i].begin(), C[i].end());
ll m = (ll)C[1].size(), n = (ll)C[2].size(), p = (ll)C[3].size(), q = (ll)C[4].size();
ll dp[m+1][n+1][p+1][q+1], last[m+1][n+1][p+1][q+1];
memset(dp, -1, sizeof(dp)); dp[0][0][0][0] = s;
FOR(i, 0, m, 1) FOR(j, 0, n, 1) FOR(k, 0, p, 1) FOR(h, 0, q, 1) {
if (i == 0 and j == 0 and k == 0 and h == 0) continue;
//cerr << dp[3][0][0][0];
FOR(pos, 1, 4, 1) {
ll a = i, b = j, c = k, d = h;
ll v = Fix(a, b, c, d, pos, -1);
if (a < 0 or b < 0 or c < 0 or d < 0) {
Fix(a, b, c, d, pos, 1);
continue;
}
ll res = (dp[a][b][c][d] - C[pos][v].p) * pos;
if (res > Inf) res = Inf;
Fix(a, b, c, d, pos, 1);
if (res < 0) continue;
if (res > dp[a][b][c][d]) {
last[a][b][c][d] = pos;
dp[a][b][c][d] = res;
}
}
}
vector<int> num, res; int now = -1;
FOR(i, 0, m, 1) FOR(j, 0, n, 1) FOR(k, 0, p, 1) FOR(h, 0, q, 1) {
if (i + j + k + h <= now or dp[i][j][k][h] < 0) continue;
if (dp[i][j][k][h] >= 0) {
now = i + j + k + h;
num = {i, j, k, h};
}
}
ll a = num[0], b = num[1], c = num[2], d = num[3];
while (true) {
if (a == 0 and b == 0 and c == 0 and d == 0) break;
ll pos = last[a][b][c][d];
ll v = Fix(a, b, c, d, pos, -1);
res.pb(C[pos][v].pos);
}
reverse(res.begin(), res.end());
return res;
}
int main() {
cin >> n >> s;
FOR(i, 0, n-1, 1)
cin >> a, P.pb(a);
FOR(i, 0, n-1, 1)
cin >> a, T.pb(a);
for (int p : max_coupons(s, P, T)) cout << p << " ";
}