제출 #1329139

#제출 시각아이디문제언어결과실행 시간메모리
1329139vlomaczkUplifting Excursion (BOI22_vault)C++20
0 / 100
1 ms344 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

ll M, L;

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	cin >> M >> L;
	ll n = 2*M + 1;
	vector<ll> a(n), c(n);
	for(ll i=0; i<n; ++i) cin >> a[i];
	c = a;
	ll sum = 0;
	for(ll i=0; i<n; ++i) sum += (i-M) * a[i];
	// cout << sum << "\n";

	//Compute the greedy (c[i] - taken by the greedy)
	ll took = 0;
	if(sum < L) {
		for(ll i=M; i<n; ++i) {
			took += (i-M) * a[i];
		}
		if(took < L) {
			cout << "impossible\n";
			return 0;
		}
		for(ll i=M-1; i>=0; --i) {
			if(took + (i-M) * a[i] >= L) {
				took += (i-M) * a[i];
			} else {
				c[i] = (took - L)/(M-i);
				took += (i-M) * ((took - L)/(M-i));
			}
		}
	} else {
		for(ll i=0; i<=M; ++i) {
			took += (i-M) * a[i];
		}
		if(took > L) {
			cout << "impossible\n";
			return 0;
		}
		for(ll i=M+1; i<n; ++i) {
			if(took + (i-M) * a[i] <= L) {
				took += (i-M) * a[i];
			} else {
				c[i] = (L-took)/(i-M);
				took += (i-M) * ((L-took)/(i-M));
			}
		}
	}
	// cout << took << "\n";
	ll cnt = 0;
	for(ll i=0; i<n; ++i) {
		cnt += c[i];
		// cout << c[i] << " ";
	}
	// cout << "\n";

	//Regret the greedy using dp and fact that we can always maintaing the transition inside tha [L-M, L+M] and obtaining same weight twice can only worsen our solution (for prove look in editorial - https://www.boi2022.de/wp-content/uploads/2022/05/boi2022-day1-vault-spoiler.pdf)
	vector<ll> dp(n, -2e18);
	ll offset = L-M;
	dp[took-offset] = cnt;
	auto remove = [&](ll x) {
		vector<ll> ndp = dp;
		ll L = max(0LL, -x);
		ll R = min(n-1, n-1-x);
		for(ll i=L; i<=R; ++i) {
			ndp[i] = max(dp[i], dp[i+x] - 1);
		}
		swap(dp, ndp);
	};
	auto add = [&](ll x) {
		vector<ll> ndp = dp;
		ll L = max(0LL, x);
		ll R = min(n-1, n-1+x);
		for(ll i=L; i<=R; ++i) {
			ndp[i] = max(dp[i], dp[i-x] + 1);
		}
		swap(dp, ndp);	
	};
	for(ll i=0; i<n; ++i) {	
		for(ll j=0; j<min(2*M+5, c[i]); ++j) remove(i-M);
		for(ll j=0; j<min(2*M+5, a[i]-c[i]); ++j) add(i-M);
	}
	if(dp[L - offset]<=0) cout << "impossible\n";
	else cout << dp[L-offset] << "\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...
#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...