結果

問題 No.3329 Only the Rightest Choice is Right!!!
コンテスト
ユーザー elphe
提出日時 2025-08-11 13:39:44
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
RE  
実行時間 -
コード長 3,065 bytes
コンパイル時間 3,010 ms
コンパイル使用メモリ 292,928 KB
実行使用メモリ 11,296 KB
最終ジャッジ日時 2025-09-09 17:12:21
合計ジャッジ時間 15,867 ms
ジャッジサーバーID
(参考情報)
judge3 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 4 RE * 4 TLE * 1 -- * 65
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>

static inline constexpr std::set<uint_fast32_t> solve(const uint_fast32_t N, const uint_fast32_t W, const std::vector<std::tuple<uint_fast32_t, uint_fast32_t, uint_fast32_t>>& items) noexcept
{
	uint_fast32_t best_value = 0;
	std::set<uint_fast32_t> ans, cur;

	std::vector<uint_fast32_t> csum_value(N + 1, 0), csum_weight(N + 1, 0);
	for (uint_fast32_t i = 0; i != N; ++i)
		csum_value[i + 1] = csum_value[i] + std::get<0>(items[i]), csum_weight[i + 1] = csum_weight[i] + std::get<1>(items[i]);

	const auto dfs = [&](const auto self, const uint_fast32_t cur_pos = 0, const uint_fast32_t total_value = 0, const uint_fast32_t total_weight = 0, uint_fast32_t csum_seek = 0) constexpr noexcept -> void
		{
			if (total_weight > W) return;
			else if (cur_pos == N)
			{
				if (total_value > best_value || (total_value == best_value && ans < cur))
					ans = cur, best_value = total_value;
				return;
			}

			for (; csum_seek != N + 1 && total_weight + (csum_weight[csum_seek] - csum_weight[cur_pos]) <= W; ++csum_seek);

			if (csum_seek != N + 1)
			{
				if (total_value + (csum_value[csum_seek - 1] - csum_value[cur_pos]) + std::get<0>(items[csum_seek - 1]) * (W - total_weight - (csum_weight[csum_seek - 1] - csum_weight[cur_pos])) / static_cast<double>(std::get<1>(items[csum_seek - 1])) >= best_value)
				{
					cur.insert(std::get<2>(items[cur_pos]));
					self(self, cur_pos + 1, total_value + std::get<0>(items[cur_pos]), total_weight + std::get<1>(items[cur_pos]), csum_seek);
					cur.erase(std::get<2>(items[cur_pos]));
					self(self, cur_pos + 1, total_value, total_weight, csum_seek);
				}
			}
			else
			{
				for (uint_fast32_t i = cur_pos; i != N; ++i)
					cur.insert(std::get<2>(items[i]));
				if (total_value + (csum_value[csum_seek - 1] - csum_value[cur_pos]) > best_value || (total_value + (csum_value[csum_seek - 1] - csum_value[cur_pos]) == best_value && ans < cur))
					ans = cur, best_value = total_value + (csum_value[csum_seek - 1] - csum_value[cur_pos]);
				for (int_fast32_t i = N - 1; i >= cur_pos; --i)
					cur.erase(std::get<2>(items[i]));
			}
		};

	dfs(dfs);
	return ans;
}

static inline void output(const std::set<uint_fast32_t>& ans) noexcept
{
	std::cout << ans.size() << '\n' << *ans.begin();
	for (auto itr = std::next(ans.begin()); itr != ans.end(); ++itr)
		std::cout << ' ' << *itr;
	std::cout << '\n';
}

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

	uint_fast32_t N, W, i;
	std::cin >> N >> W;
	std::vector<std::tuple<uint_fast32_t, uint_fast32_t, uint_fast32_t>> items(N);
	for (i = 0; i != N; ++i)
		std::cin >> std::get<0>(items[i]);
	for (i = 0; i != N; ++i)
		std::cin >> std::get<1>(items[i]);
	for (i = 0; i != N; ++i)
		std::get<2>(items[i]) = i + 1;

	std::sort(items.begin(), items.end(), [](const std::tuple<uint_fast32_t, uint_fast32_t, uint_fast32_t>& a, const std::tuple<uint_fast32_t, uint_fast32_t, uint_fast32_t>& b) { return std::get<0>(a) * std::get<1>(b) > std::get<0>(b) * std::get<1>(a); });
	output(solve(N, W, items));
	return 0;
}
0