結果

問題 No.921 ずんだアロー
ユーザー qwewe
提出日時 2025-05-14 13:09:15
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 10 ms / 2,000 ms
コード長 4,948 bytes
コンパイル時間 627 ms
コンパイル使用メモリ 74,804 KB
実行使用メモリ 6,272 KB
最終ジャッジ日時 2025-05-14 13:10:22
合計ジャッジ時間 1,856 ms
ジャッジサーバーID
(参考情報)
judge1 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 22
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#include <algorithm>

// Use long long for DP states to prevent potential overflow, although unlikely given N <= 10^5.
// The maximum count could theoretically be N, which fits within a standard 32-bit integer.
// However, using long long is safer and doesn't significantly impact performance here.
using ll = long long;

int main() {
    // Optimize standard I/O operations for speed.
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(NULL);
    
    int N; // Number of mochi
    std::cin >> N;
    
    // Handle edge case: N=0. If there are no mochi, the maximum count is 0.
    if (N == 0) {
        std::cout << 0 << std::endl;
        return 0;
    }
    
    // Read the sizes of the N mochi into a vector.
    std::vector<int> A(N);
    for (int i = 0; i < N; ++i) {
        std::cin >> A[i];
    }
    
    // Handle edge case: N=1. If there is only one mochi, we can select it. Max count is 1.
    if (N == 1) {
        std::cout << 1 << std::endl;
        return 0;
    }
    
    // We use dynamic programming with constant space optimization.
    // We maintain two variables representing the DP states for the previous index `i-1`.
    
    // `prev_0`: stores the maximum count considering elements up to index `i-1`, 
    //           where the element at index `i-1` is NOT selected.
    // `prev_1`: stores the maximum count considering elements up to index `i-1`,
    //           where the element at index `i-1` IS selected.
    ll prev_0 = 0; 
    ll prev_1 = 0; 
    
    // Initialize the DP states after conceptually processing the first element (at index 0).
    // Base case for index 0:
    // - If we don't select the mochi at index 0: Max count is 0. (This corresponds to `prev_0` for i=1)
    // - If we select the mochi at index 0: Max count is 1. (This corresponds to `prev_1` for i=1)
    prev_0 = 0;
    prev_1 = 1;

    // Iterate through the array starting from the second element (index 1) up to N-1.
    for (int i = 1; i < N; ++i) {
        // Calculate the DP states for the current index `i`.
        ll curr_0 = 0; // max count up to index `i`, with index `i` NOT selected.
        ll curr_1 = 0; // max count up to index `i`, with index `i` selected.
        
        // Calculate `curr_0`: maximum count up to index `i`, with `i` NOT selected.
        // If we don't select element `i`, the maximum count is simply the maximum possible count
        // achieved up to index `i-1`, regardless of whether `i-1` was selected or not selected.
        // This is the max of the two states from the previous step.
        curr_0 = std::max(prev_0, prev_1);
        
        // Calculate `curr_1`: maximum count up to index `i`, with `i` selected.
        // This decision depends on the sizes of mochi at indices `i` and `i-1`.
        // The problem states that if two adjacent zunda mochi have different sizes, the smaller one disappears.
        // To maximize the final count, we should select an initial set such that no mochi disappears.
        // This means if we select both mochi at `i` and `i-1`, their sizes must be equal (`A[i] == A[i-1]`).
        
        if (A[i] == A[i-1]) {
            // If sizes are equal, selecting `i` is compatible with selecting `i-1`.
            // We can transition from either state at `i-1`:
            // Case 1: Select `i`, after selecting `i-1`. The maximum score path ending with `i-1` selected is `prev_1`. Total score: `1 + prev_1`.
            // Case 2: Select `i`, after NOT selecting `i-1`. The maximum score path ending with `i-1` not selected is `prev_0`. Total score: `1 + prev_0`.
            // We take the maximum of these two possible transitions to get the best score ending with `i` selected.
            curr_1 = 1 + std::max(prev_0, prev_1); 
        } else {
            // If sizes are different (`A[i] != A[i-1]`), we cannot select `i` if `i-1` was also selected,
            // because one of them would disappear, leading to a suboptimal count.
            // Therefore, to select `i`, we must NOT have selected `i-1`.
            // We must transition from the state where `i-1` was NOT selected (`prev_0`).
            // The total score is `1` (for selecting `i`) plus the max score ending at `i-1` not selected (`prev_0`).
            curr_1 = 1 + prev_0;
        }
        
        // Update the DP states for the next iteration (`i+1`).
        // The calculated current states (`curr_0`, `curr_1`) become the "previous" states for the next step.
        prev_0 = curr_0;
        prev_1 = curr_1;
    }
    
    // After iterating through all elements up to `N-1`, the final answer is the maximum
    // possible count achievable considering all N elements. This is the maximum of the two final states:
    // either the last element (at `N-1`) was selected (`prev_1`) or it was not selected (`prev_0`).
    std::cout << std::max(prev_0, prev_1) << std::endl;
    
    return 0;
}
0