All IOI entries
Competitive Programming

IOI 1989 - Problem 2: Strings

Deriving the Recurrence Let f(n) denote the count of valid binary strings of length n. Partition these strings by their last character: a(n): valid strings of length n ending in 0. b(n): valid strings of length n endi...

Source sync Apr 19, 2026
Track IOI
Year 1989
Files TeX and C++
Folder competitive_programming/ioi/1989/strings
IOI1989TeXC++

Source-first archive entry

This page is built from the copied files in competitive_programming/ioi/1989/strings. Edit competitive_programming/ioi/1989/strings/solution.tex to update the written solution and competitive_programming/ioi/1989/strings/solution.cpp to update the implementation.

The website does not replace those files with hand-maintained HTML. It reads the copied source tree during the build and exposes the exact files below.

Problem Statement

Rendered from the "Problem Statement" section inside solution.tex because this entry has no separate statement file.

Count the number of binary strings of length $n$ that contain no two consecutive 1s.

Editorial

Rendered from the copied solution.tex file. The original TeX source remains available below.

Solution

Deriving the Recurrence

Let $f(n)$ denote the count of valid binary strings of length $n$. Partition these strings by their last character:

  • $a(n)$: valid strings of length $n$ ending in 0.

  • $b(n)$: valid strings of length $n$ ending in 1.

  • Then $f(n) = a(n) + b(n)$, with recurrences:

\begin{align}a(n) &= a(n-1) + b(n-1), \\ b(n) &= a(n-1). \end{align}

The first equation holds because 0 can follow either ending. The second holds because 1 can only follow 0 (to avoid consecutive 1s).

Substituting: \[ f(n) = a(n) + b(n) = f(n-1) + a(n-1) = f(n-1) + f(n-2), \] where the last step uses $a(n-1) = a(n-2) + b(n-2) = f(n-2)$.

Theorem.

$f(n) = F_{n+2}$, where $F_k$ is the $k$-th Fibonacci number with $F_1 = F_2 = 1$.

Proof.

By induction. We have $f(1) = 2 = F_3$ and $f(2) = 3 = F_4$. For $n \ge 3$, $f(n) = f(n-1) + f(n-2) = F_{n+1} + F_n = F_{n+2}$.

Complexity Analysis

  • Time: $O(n)$ using iterative computation.

  • Space: $O(1)$, since only the two most recent values are needed.

Implementation

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;

    if (n == 0) {
        cout << 1 << endl;  // the empty string
        return 0;
    }
    if (n == 1) {
        cout << 2 << endl;
        return 0;
    }

    long long prev2 = 2;  // f(1)
    long long prev1 = 3;  // f(2)

    for (int i = 3; i <= n; i++) {
        long long cur = prev1 + prev2;
        prev2 = prev1;
        prev1 = cur;
    }

    cout << prev1 << endl;
    return 0;
}

Verification

$n$$f(n)$Valid strings
120, 1
2300, 01, 10
35000, 001, 010, 100, 101
480000, 0001, 0010, 0100, 0101, 1000, 1001, 1010
513(Fibonacci pattern continues)

The sequence $2, 3, 5, 8, 13, 21, \ldots$ matches $F_3, F_4, F_5, \ldots$, confirming the formula.

Note on Overflow

For $n > 85$, the value of $f(n)$ exceeds the range of a 64-bit integer. If larger values of $n$ are needed, arbitrary-precision arithmetic (e.g., Python integers or a big-integer library) should be used.

Code

Exact copied C++ implementation from solution.cpp.

C++ competitive_programming/ioi/1989/strings/solution.cpp

Exact copied implementation source.

Raw file
// IOI 1989 - Problem 2: Strings
// Count binary strings of length n with no two consecutive 1s.
// Recurrence: f(n) = f(n-1) + f(n-2), f(1)=2, f(2)=3 (Fibonacci variant)
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    scanf("%d", &n);

    if (n == 0) { printf("1\n"); return 0; }
    if (n == 1) { printf("2\n"); return 0; }

    long long prev2 = 2; // f(1)
    long long prev1 = 3; // f(2)
    for (int i = 3; i <= n; i++) {
        long long cur = prev1 + prev2;
        prev2 = prev1;
        prev1 = cur;
    }
    printf("%lld\n", prev1);
    return 0;
}

Source Files

Exact copied source-of-truth files. Edit solution.tex for the write-up and solution.cpp for the implementation.

TeX write-up competitive_programming/ioi/1989/strings/solution.tex

Exact copied write-up source.

Raw file
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amssymb,amsthm}
\usepackage{listings}
\usepackage[margin=2.5cm]{geometry}
\usepackage{xcolor}

\newtheorem{theorem}{Theorem}
\newtheorem{lemma}[theorem]{Lemma}

\lstset{
  language=C++,
  basicstyle=\ttfamily\small,
  keywordstyle=\color{blue}\bfseries,
  commentstyle=\color{green!50!black},
  stringstyle=\color{red!70!black},
  numbers=left,
  numberstyle=\tiny\color{gray},
  breaklines=true,
  frame=single,
  tabsize=4,
  showstringspaces=false
}

\title{IOI 1989 -- Problem 2: Strings}
\author{Solution}
\date{}

\begin{document}
\maketitle

\section{Problem Statement}

Count the number of binary strings of length $n$ that contain no two
consecutive \texttt{1}s.

\section{Solution}

\subsection{Deriving the Recurrence}

Let $f(n)$ denote the count of valid binary strings of length~$n$. Partition
these strings by their last character:
\begin{itemize}
  \item $a(n)$: valid strings of length $n$ ending in \texttt{0}.
  \item $b(n)$: valid strings of length $n$ ending in \texttt{1}.
\end{itemize}

Then $f(n) = a(n) + b(n)$, with recurrences:
\begin{align}
  a(n) &= a(n-1) + b(n-1), \\
  b(n) &= a(n-1).
\end{align}
The first equation holds because \texttt{0} can follow either ending. The
second holds because \texttt{1} can only follow \texttt{0} (to avoid
consecutive \texttt{1}s).

Substituting:
\[
  f(n) = a(n) + b(n) = f(n-1) + a(n-1) = f(n-1) + f(n-2),
\]
where the last step uses $a(n-1) = a(n-2) + b(n-2) = f(n-2)$.

\begin{theorem}
$f(n) = F_{n+2}$, where $F_k$ is the $k$-th Fibonacci number with
$F_1 = F_2 = 1$.
\end{theorem}
\begin{proof}
By induction. We have $f(1) = 2 = F_3$ and $f(2) = 3 = F_4$. For $n \ge 3$,
$f(n) = f(n-1) + f(n-2) = F_{n+1} + F_n = F_{n+2}$.
\end{proof}

\section{Complexity Analysis}

\begin{itemize}
  \item \textbf{Time:} $O(n)$ using iterative computation.
  \item \textbf{Space:} $O(1)$, since only the two most recent values are
    needed.
\end{itemize}

\section{Implementation}

\begin{lstlisting}
#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;

    if (n == 0) {
        cout << 1 << endl;  // the empty string
        return 0;
    }
    if (n == 1) {
        cout << 2 << endl;
        return 0;
    }

    long long prev2 = 2;  // f(1)
    long long prev1 = 3;  // f(2)

    for (int i = 3; i <= n; i++) {
        long long cur = prev1 + prev2;
        prev2 = prev1;
        prev1 = cur;
    }

    cout << prev1 << endl;
    return 0;
}
\end{lstlisting}

\section{Verification}

\begin{center}
\begin{tabular}{|c|c|l|}
\hline
$n$ & $f(n)$ & Valid strings \\
\hline
1 & 2 & \texttt{0}, \texttt{1} \\
2 & 3 & \texttt{00}, \texttt{01}, \texttt{10} \\
3 & 5 & \texttt{000}, \texttt{001}, \texttt{010}, \texttt{100}, \texttt{101} \\
4 & 8 & \texttt{0000}, \texttt{0001}, \texttt{0010}, \texttt{0100},
        \texttt{0101}, \texttt{1000}, \texttt{1001}, \texttt{1010} \\
5 & 13 & (Fibonacci pattern continues) \\
\hline
\end{tabular}
\end{center}

The sequence $2, 3, 5, 8, 13, 21, \ldots$ matches $F_3, F_4, F_5, \ldots$,
confirming the formula.

\section{Note on Overflow}

For $n > 85$, the value of $f(n)$ exceeds the range of a 64-bit integer.
If larger values of $n$ are needed, arbitrary-precision arithmetic (e.g.,
Python integers or a big-integer library) should be used.

\end{document}