結果
問題 |
No.2329 Nafmo、イカサマをする
|
ユーザー |
![]() |
提出日時 | 2025-05-14 12:58:43 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,721 bytes |
コンパイル時間 | 622 ms |
コンパイル使用メモリ | 85,268 KB |
実行使用メモリ | 93,220 KB |
最終ジャッジ日時 | 2025-05-14 13:00:07 |
合計ジャッジ時間 | 5,442 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 37 TLE * 2 -- * 1 |
ソースコード
#include <iostream> #include <vector> #include <set> #include <algorithm> // Use long long for scores as they can potentially become large. // A_i can be up to 10^9, K up to 6. Max score can be up to 6 * 10^9. using Score = long long; int main() { // Use faster I/O operations std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); int N; // Number of cards Score M; // Maximum allowed score int K; // Maximum number of draws allowed std::cin >> N >> M >> K; // Use a set to store distinct card values. This automatically handles duplicates. // We only care about distinct values Nafmo can choose from. // Also, only values <= M are relevant. If a card value is > M, choosing it // would immediately make the score > M (assuming scores are non-negative), // so Nafmo would never choose such a card if aiming for a score <= M. // We assume card values A_i are non-negative based on problem context/examples. std::set<Score> unique_A_le_M; for (int i = 0; i < N; ++i) { Score card_value; std::cin >> card_value; // Only consider card values that are non-negative and less than or equal to M. if (card_value >= 0 && card_value <= M) { unique_A_le_M.insert(card_value); } } // The dynamic programming approach will compute sets of achievable scores. // `current_scores` will hold the set of scores achievable after exactly k-1 draws. // It starts with score 0 after 0 draws. std::set<Score> current_scores; current_scores.insert(0); // `all_possible_scores` tracks all unique scores achievable within K draws that are <= M. // Initialize with 0, which is always achievable by drawing 0 cards. std::set<Score> all_possible_scores; all_possible_scores.insert(0); // Iterate from 1 to K draws for (int k = 1; k <= K; ++k) { // `next_scores` will store scores achievable after exactly k draws. std::set<Score> next_scores; // Optimization: If `current_scores` is empty, it means no score <= M was reachable // in the previous step (k-1 draws). Therefore, no scores <= M can be generated // in this step (k draws) or subsequent steps. We can break the loop early. if (current_scores.empty()) { break; } // Explore states reachable from scores achieved in k-1 draws // For each score 's' achievable in k-1 draws: for (Score s : current_scores) { // Try adding each distinct available card value 'val' (where val <= M) for (Score val : unique_A_le_M) { // Calculate the potential next score Score next_s = s + val; // Check if the potential score `next_s` does not exceed the maximum allowed score M if (next_s <= M) { // Add `next_s` to the set of scores achievable in exactly k draws. // `std::set` automatically handles duplicates: if `next_s` is already present, insert does nothing. next_scores.insert(next_s); // Also, record `next_s` in the set of all possible scores found so far (across all k' <= k draws). // This set will contain scores from all step counts 0 up to the current k. all_possible_scores.insert(next_s); } } } // Prepare for the next iteration (k+1 draws): // The scores computed for step k (`next_scores`) become the basis (`current_scores`) for step k+1. // `std::move` is used for potential performance optimization, especially if sets become large. // It efficiently transfers ownership of the set's contents without copying. current_scores = std::move(next_scores); } // After the loop finishes (either completing K steps or breaking early), // `all_possible_scores` contains all unique scores <= M achievable by drawing at most K cards. // We need the maximum among these scores. Score max_score = 0; // Default score is 0, achievable by drawing 0 cards. // Check if `all_possible_scores` is non-empty. It should contain at least 0 if M >= 0. if (!all_possible_scores.empty()) { // `rbegin()` returns a reverse iterator pointing to the largest element in the `std::set` (which is sorted). // Dereferencing it gives the maximum value. max_score = *all_possible_scores.rbegin(); } // Output the maximum achievable score <= M. std::cout << max_score << std::endl; return 0; }