cppAcademy
FROM LEARNING TO COMPETING

Proficient.
Put your skills to the test.

Bulgarian Informatics Group B · 2009–2026

217 independently explained problems: 54 Municipal, 54 Regional and 109 National. Start with the easier tasks and work upwards. Difficulty labels are learning estimates, not official ratings; Group B also includes challenging national-level problems. National-round tasks shared by Groups A and B are included. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP B2010 · MediumDynamic programming

Two Counters

National Olympiad — Regional round (2010 season)

Submission name: shift.cpp

Problem summary

Two distinguishable counters A and B start on squares n−1 and n of a strip. A move shifts one counter one square left into a free square. Count the move sequences ending with A at p and B at q.

Input

p q n.

Output

The number of valid move sequences.

Constraints

1 ≤ p < q ≤ n ≤ 16.

Worked example

An independently prepared example for this explanation.

Input

1 3 4

Output

2

Solution analysis

  1. Let dp[a][b] count sequences reaching the ordered positions a<b. Initialize dp[n−1][n]=1. A can move to a−1 while a>p; B can move to b−1 while b>q and b−1>a.
  2. Process a and b in descending order. Both moves decrease a coordinate, so every predecessor is processed before its successors. Add counts to both legal next states.
  3. For p=1,q=3,n=4, A needs two moves and B one. AAB and ABA are legal; BAA is blocked on its first move. The answer is 2.

Why it works

Counters never cross, so every reachable state has a<b. The two transitions are precisely the legal moves that do not pass their targets. Any sequence reaching a state has a unique final move from one of its predecessors; adding their counts counts every sequence once. Descending iteration respects the transition order.

Complexity: O(n²) time and O(n²) space.

Watch out. The counters are distinguishable. B cannot enter A’s square. Use 64-bit counts; even the unrestricted count of at most 28 moves fits.

Commented C++17 solution

An independently written complete program with standard headers.

#include<iostream>
using namespace std;
int main(){
    // Compute the exact archive answer using the method explained above.
    int p,q,n;
    cin>>p>>q>>n;
    long long dp[17][17]={};
    dp[n-1][n]=1;
    for(int a=n-1;a>=p;a--){
        for(int b=n;b>=q;b--){
            if(a>=b){
                continue;
            }
            if(a>p){
                dp[a-1][b]+=dp[a][b];
            }
            if(b>q&&b-1>a){
                dp[a][b-1]+=dp[a][b];
            }
        }
    }
    cout<<dp[p][q]<<'\n';
}

Source: Arena Olimpiici ↗