公式

E - カードの消去ゲーム / Card Elimination Game 解説 by admin 印刷ページ

claude4.8opus-high

Overview

This is a problem asking whether we can erase adjacent pairs of cards with the same color and integer from \(N\) cards such that the remaining cards match the string \(T\) and the integer sequence \(Q\) exactly. In fact, since “integers can be written freely,” the determination reduces to whether subsegments can be fully erased based solely on the sequence of colors.

Analysis

Integers (\(Q\), \(M\)) do not affect the answer

First, an important key observation: the erasure operation requires that “the integers of the erased pair are equal,” but Takahashi can freely write any integer.

  • The erased cards are eliminated in 1-to-1 pairs. We can simply assign the same integer (for example, \(1\)) to each pair, which is always possible since \(M \geq 1\).
  • For the cards that remain at the end, we can simply write the target \(Q_i\) directly, which is guaranteed by the constraint \(Q_i \leq M\). Since the remaining cards are not erased, there are no additional constraints regarding their integers.

Therefore, \(Q\) and \(M\) have no effect on the determination at all, and we only need to consider “whether subsegments can be fully erased using only the color conditions” and “whether the sequence of characters matches \(T\).”

Conditions for a subsegment to be “fully erased”

Let us consider whether a contiguous subsegment can be completely erased. Erasing cards by “adjacent pairs of the same color” is very similar to parenthesis matching.

Let \(R[a][b]\) denote whether the interval \([a, b)\) (from left endpoint \(a\) to right endpoint \(b-1\)) can be completely erased. Focusing on the leftmost card \(a\) in the interval, \(a\) will eventually pair up with some card \(k\) of the same color and be erased. For this to happen, it is necessary and sufficient that:

  • Card \(a\) and card \(k\) have the same color,
  • The interval \([a+1, k)\) between \(a\) and \(k\) can be fully erased first (\(R[a+1][k]\)),
  • The interval \([k+1, b)\) to the right of \(k\) can also be fully erased (\(R[k+1][b]\)).

Thus, we can formulate the following interval DP (the length must be even):

\[R[a][b] = \bigvee_{a<k<b,\ \text{col}[a]=\text{col}[k]} \big(R[a+1][k] \land R[k+1][b]\big)\]

Here, \(R[a][a] = \text{true}\) (empty interval).

Conditions for leaving the string \(T\)

Next, let us consider selecting the remaining cards from left to right so that their string matches \(T\).

When matching up to the \(j\)-th target character \(T[j]\), we maintain “the position immediately after the last selected card” as our state. Moving from position \(a\) to the next selected card \(v\) (where \(S[v] = T[j]\)) is possible when the interval \([a, v)\) between them can be fully erased, that is, when \(R[a][v]\) is true.

  • Start at position \(0\) (empty before the beginning).
  • Every time a character is matched, update the set of reachable “next starting positions \(v+1\)”.
  • Finally, if there is a reached position \(a\) such that \(R[a][N]\) is true from position \(a\) to the end \(N\), all remaining cards can be erased, completing the sequence.

Algorithm

  1. Interval Erasure DP: Fill the above \(R[a][b]\) in order of interval lengths \(2, 4, \dots\).
  2. Reachable Positions DP: Maintain a set reach representing “which positions can currently be a boundary.” Process \(T\) character by character from the beginning, updating reach.
    • Each bit \(a\) in reach represents that “we can proceed from starting position \(a\).”
    • For a card \(v\) matching the target character, if (reach & colR[v]) is non-empty (i.e., there exists an \(a\) such that \(R[a][v]\) is true), set the new position \(v+1\) as reachable.
    • Here, colR[v] is a bitset representing “the set of \(a\) for which \(R[a][v]\) is true.”
  3. Finally, if reach & colR[N] is non-empty, the answer is Yes.

Using bitset for set operations speeds up the bitwise AND and non-empty checks.

Complexity

  • Time Complexity: Interval DP takes \(O(N^3)\), and reachability DP takes \(O(L \cdot N^2 / w)\) using bitsets (where \(w\) is the word size). Overall time complexity is \(O(N^3)\).
  • Space Complexity: The DP table \(R\) takes \(O(N^2)\), and the bitset structures take \(O(N^2 / w)\). Overall space complexity is \(O(N^2)\).

Since \(N \le 1000\), \(O(N^3)\) is around \(10^9\) operations. However, because the interval length loop increments by even steps and the inner operations are simple logical operations, it will easily run within the time limit in C++.

Implementation Points

  • Read \(Q\) and \(M\), but do not use them for determination: As mentioned earlier, since integers can be assigned freely, the answer depends solely on colors and characters. Do not get distracted by them.

  • Interval lengths are even only: An odd number of cards cannot be fully erased, so using len += 2 halves the computation count.

  • Column-wise bitset colR[b]: Storing \(R[a][b]\) as a bitset representing “for each right endpoint \(b\), the set of left endpoints \(a\) that make \(R[a][b]\) true” allows checking whether we can proceed with a single bitwise AND operation with reach. This is the key optimization of this approach.

  • Early termination if unreachable: If reach becomes empty after processing a character, it can never be satisfied afterwards, so set a fail flag and exit early.

    Source Code

#include <bits/stdc++.h>
using namespace std;

int main(){
    int N,M,L;
    scanf("%d %d %d",&N,&M,&L);
    static char buf[3000];
    scanf("%s",buf); string S=buf;
    scanf("%s",buf); string P=buf;
    scanf("%s",buf); string T=buf;
    vector<int> Q(L);
    for(int i=0;i<L;i++) scanf("%d",&Q[i]);

    vector<int> col(N);
    for(int i=0;i<N;i++) col[i]=P[i]-'A';

    // R[a][b] : cards a..b-1 are fully reducible (by same-color adjacent removal)
    vector<vector<char>> R(N+1, vector<char>(N+1, 0));
    for(int a=0;a<=N;a++) R[a][a]=1;
    for(int len=2; len<=N; len+=2){
        for(int a=0; a+len<=N; a++){
            int b=a+len;
            char ok=0;
            for(int k=a+1;k<b;k++){
                if(col[k]==col[a] && R[a+1][k] && R[k+1][b]){ ok=1; break; }
            }
            R[a][b]=ok;
        }
    }

    // column bitsets: colR[b] has bit a set iff R[a][b]
    vector<bitset<1001>> colR(N+1);
    for(int b=0;b<=N;b++){
        for(int a=0;a<=b;a++) if(R[a][b]) colR[b].set(a);
    }

    bitset<1001> reach;
    reach.set(0); // gap starts at index 0
    bool fail=false;
    for(int j=0;j<L && !fail;j++){
        bitset<1001> nxt;
        char tc=T[j];
        for(int v=0;v<N;v++){
            if(S[v]!=tc) continue;
            if((reach & colR[v]).any()) nxt.set(v+1);
        }
        reach=nxt;
        if(reach.none()) fail=true;
    }

    bool ans=false;
    if(!fail){
        ans = (reach & colR[N]).any();
    }
    printf(ans?"Yes\n":"No\n");
    return 0;
}

This editorial was generated by claude4.8opus-high.

投稿日時:
最終更新: