結果

問題 No.1522 Unfairness
ユーザー qwewe
提出日時 2025-05-14 13:06:25
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
TLE  
実行時間 -
コード長 6,708 bytes
コンパイル時間 1,391 ms
コンパイル使用メモリ 95,348 KB
実行使用メモリ 32,672 KB
最終ジャッジ日時 2025-05-14 13:07:32
合計ジャッジ時間 4,753 ms
ジャッジサーバーID
(参考情報)
judge3 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other TLE * 1 -- * 26
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
#include <map>

using namespace std;

// Using -1 to represent unreachable/invalid states. 
// We use long long for O sums as they can potentially exceed 32-bit integer capacity.
// The maximum possible O can be roughly N/2 * max(A_i) = 1500 * 10^6 = 1.5 * 10^9, which fits in 32-bit signed int,
// but sum could exceed 2^31 - 1. Using long long is safer.
const long long INF = -1; 

int main() {
    // Faster I/O operations
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int N; // Number of elements in the array A
    long long M; // Maximum allowed unfairness
    cin >> N >> M;

    vector<long long> A(N);
    for (int i = 0; i < N; ++i) {
        cin >> A[i];
    }

    // Sort the array A in descending order. This helps in the DP state transitions
    // as the element A[i] being considered is always the smallest among elements selected so far from A[0...i].
    sort(A.rbegin(), A.rend());

    // dp0[u] stores the maximum possible sum O achieved using an even number of elements (let's say j),
    // such that the calculated unfairness is exactly u. We only store states where u <= M.
    // The size is M+1 to cover indices from 0 to M.
    vector<long long> dp0(M + 1, INF);

    // dp1[u] stores the maximum possible sum O achieved using an odd number of elements (j),
    // with calculated alternating sum u. The value 'u' here is the alternating sum B_1 - B_2 + ... + B_j.
    // This 'u' can potentially exceed M for odd j states, so we use a map to store these states flexibly.
    map<long long, long long> dp1;

    // Base case: Before considering any element, we have chosen 0 elements (an even number).
    // The sum O is 0, and the unfairness U is 0. This state is valid.
    dp0[0] = 0; 

    // Iterate through each element A[i] of the sorted array (A'_1, A'_2, ..., A'_N)
    for (int i = 0; i < N; ++i) {
        long long val = A[i]; // The current element value A'_{i+1} being considered
        
        // Create temporary DP states for the next iteration. Initialize with current states.
        // This implicitly handles the option of *not* selecting the current element A[i],
        // as the previous states are carried over.
        vector<long long> next_dp0 = dp0;
        map<long long, long long> next_dp1 = dp1;

        // --- Process transitions where we *select* the current element A[i] ---

        // Transition from states with an even number of elements (dp0) to states with an odd number (next_dp1):
        // If we select A[i] and previously had an even number of elements j, the new count j+1 is odd.
        // The new element A[i] will be the (j+1)-th element in the sorted list B, which is an odd position.
        for (int u = 0; u <= M; ++u) { // Iterate through all possible unfairness values for even counts
            if (dp0[u] != INF) { // Check if the state (even count j, unfairness u) is reachable
                long long current_O = dp0[u]; // Get the maximum O for this state
                
                // Calculate the new alternating sum u'. Since A[i] is at an odd position (j+1), it adds to the sum.
                long long new_u = u + val; 
                // Calculate the new sum O'. Since A[i] is at an odd position, it contributes to O.
                long long new_O = current_O + val;
                
                // Update the state in next_dp1 map for the odd count (j+1).
                // If the key new_u doesn't exist or the new O sum is better, update/insert the value.
                if (next_dp1.find(new_u) == next_dp1.end() || new_O > next_dp1[new_u]) {
                     next_dp1[new_u] = new_O;
                 }
            }
        }

        // Transition from states with an odd number of elements (dp1) to states with an even number (next_dp0):
        // If we select A[i] and previously had an odd number of elements j, the new count j+1 is even.
        // The new element A[i] will be the (j+1)-th element in the sorted list B, which is an even position.
        for (auto const& [u, current_O] : dp1) { // Iterate through all reachable states in dp1 map
             // Note: `current_O` retrieved from `dp1` map must be valid (not INF) because we only insert valid states.

             // Calculate the new unfairness u'. Since A[i] is at an even position (j+1), it subtracts from the alternating sum.
             long long new_u = u - val;
             // Calculate the new sum O'. Since A[i] is at an even position, it does not contribute to O.
             long long new_O = current_O;

             // The alternating sum u' must be non-negative. Based on the property B_p >= B_{p+1}, this should always hold.
             // We check for safety.
             if (new_u >= 0) { 
                 // Pruning Rule: For states with an even number of elements (stored in dp0), we only care about 
                 // states where the unfairness u' is less than or equal to M.
                 if (new_u <= M) { 
                     // Update the corresponding state in next_dp0 array if this path yields a better O sum.
                     if (next_dp0[new_u] == INF || new_O > next_dp0[new_u]) {
                         next_dp0[new_u] = new_O;
                     }
                 }
                 // If new_u > M, this state is pruned because it violates the constraint for an even number of elements.
             }
             // If new_u < 0, this indicates an issue, possibly related to numerical precision or logic error,
             // but theoretically it shouldn't happen with non-negative A_i and descending sort order.
        }
        
        // After considering all transitions for A[i], update the DP states for the next iteration (processing A[i+1])
        dp0 = next_dp0;
        dp1 = next_dp1;
    }

    // After iterating through all elements, the final answer is the maximum O found in dp0[u] for any u <= M.
    // dp0 contains states with an even number of elements chosen, which corresponds to completed pairs (B_1, B_2), ..., (B_{2k-1}, B_{2k}).
    long long max_O = 0; // Initialize max_O to 0. If no valid selection is possible, the answer is 0.
                         // O represents a sum of elements from A, which are non-negative, so min O is 0.
                         
    for (int u = 0; u <= M; ++u) { // Check all possible final unfairness values up to M
        if (dp0[u] != INF) { // If a state with unfairness u is reachable
            max_O = max(max_O, dp0[u]); // Update max_O if this state gives a larger sum O
        }
    }

    // Output the final maximum O found.
    cout << max_O << endl;

    return 0;
}
0