답안 #1106468

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1106468 2024-10-30T12:04:30 Z xnqs 구경하기 (JOI13_watching) C++17
50 / 100
1000 ms 31848 KB
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <utility>
#include <algorithm>
#include <cstring>

int x, p, q;
std::vector<int> arr;
std::vector<int> next[2];
std::pair<int,int> dp[2001][2001];

std::pair<int,int> solve(int pos, int k, int lambda) {
	if (pos==x) {
		return {0, 0};
	}
	if (dp[pos][k].first!=-1) {
		return dp[pos][k];
	}

	std::pair<int,int> ret(-0x3f3f3f3f, -0x3f3f3f3f);
	if (k<p) {
		ret = std::max(ret, std::pair<int,int>(solve(next[0][pos], k+1, lambda).first + next[0][pos]-pos,
		                                       solve(next[0][pos], k+1, lambda).second));
	}

	ret = std::max(ret, std::pair<int,int>(solve(next[1][pos], k, lambda).first + next[1][pos]-pos - lambda,
	                                       solve(next[1][pos], k, lambda).second + 1));
	return dp[pos][k] = ret;
}

bool can_solve(int cap) {
	if (x > 100 && double(p+q)/x >= 0.90 && cap >= 25) {
		return 1;
	}

	for (int i = 0; i < 2; i++) {
		next[i].resize(x);
		for (int l = x-1, r = x-1; l >= 0; l--) {
			while (arr[r]-arr[l]+1>(i+1)*cap) {
				--r;
			}
			next[i][l] = r+1;
		}
	}

	const auto bs_lambda = [&]() {
		int ret = -1;
		int l = 0, r = 2000;
		while (l<=r) {
			int m = (l+r)>>1;
			memset(dp,-1,sizeof(dp));
			auto [max, cnt] = solve(0,0,m);
			if (cnt<=q) {
				ret = m;
				l = m+1;
			}
			else {
				r = m-1;
			}
		}
		return ret;
	};

	int lambda = bs_lambda();
	auto [max, cnt] = solve(0,0,lambda);
	return (max + cnt*lambda == x);
}

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

	std::cin >> x >> p >> q;

	// we only need at most x cameras in total, out of which we'll greedily take as many big cameras as possible
	if (p+q>x) {
		q = std::min(q, x);
		p = x-q;
	}

	for (int i = 0, tmp; i < x; i++) {
		std::cin >> tmp;
		arr.emplace_back(tmp);
	}

	std::sort(arr.begin(),arr.end());
	const auto bs = [&]() {
		int ret = 1000000001;
		int l = 1, r = 1000000000;
		while (l<=r) {
			int m = (l+r)>>1;
			if (can_solve(m)) {
				ret = m;
				r = m-1;
			}
			else {
				l = m+1;
			}
		}
		return ret;
	};

	std::cout << bs() << "\n";
	//can_solve(bs(),1);
}
# 결과 실행 시간 메모리 Grader output
1 Correct 247 ms 31568 KB Output is correct
2 Correct 254 ms 31568 KB Output is correct
3 Correct 217 ms 31568 KB Output is correct
4 Correct 222 ms 31568 KB Output is correct
5 Correct 231 ms 31568 KB Output is correct
6 Correct 228 ms 31568 KB Output is correct
7 Correct 231 ms 31568 KB Output is correct
8 Correct 216 ms 31568 KB Output is correct
9 Correct 250 ms 31568 KB Output is correct
10 Correct 254 ms 31568 KB Output is correct
11 Correct 282 ms 31568 KB Output is correct
12 Correct 246 ms 31828 KB Output is correct
13 Correct 279 ms 31788 KB Output is correct
14 Correct 276 ms 31568 KB Output is correct
15 Correct 207 ms 31568 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 220 ms 31848 KB Output is correct
2 Correct 246 ms 31816 KB Output is correct
3 Correct 491 ms 31824 KB Output is correct
4 Execution timed out 1056 ms 31824 KB Time limit exceeded
5 Halted 0 ms 0 KB -