Project Euler #15: counting paths through a 20 × 20 grid I've recently solved Project Euler's 15th problem stating:


  Starting in the top left corner of a 2×2 grid, and only being able to move to the right and down, there are exactly 6 routes to the bottom right corner.
  
  How many such routes are there through a 20×20 grid?


This is my dynamic approach in C++

#include &lt;cstdio&gt;

const unsigned short n = 20;

int main() {
    unsigned long long p[n][n];
    for (unsigned short i = 2; i &lt;= n; i++)
        p[n - i][n - 1] = i + 1;
    for (unsigned short i = n - 2; i &gt;= 1; i--) {
        p[i][i] = 2 * p[i][i + 1];
        for (unsigned short k = i; k &gt;= 1; k--)
            p[k - 1][i] = p[k][i] + p[k - 1][i + 1];
    }
    printf("%llu", 2 * p[0][1]);
}


I am aware that this problem could be solved way more efficiently and faster by simply calculating \${(2n)!}/{(n!)^2}\$, however I decided to look at this problem from a programmer's point of view, rather than a mathematician's.
#include &lt;cstdio&gt;


If your goal is to write C++, you're really off to a bad start using the C standard I/O library.

const unsigned short n = 20;


The modern way to do compile time constants is with constexpr.

But I don't understand why you chose to use unsigned short for all your indexing calculations. Any operations you try to do on it will automatically promote it to unsigned int. You're not really gaining anything.

for (unsigned short i = 2; i &lt;= n; i++)


Once again, once you've bought into unsigned short, you keep using it everywhere. But aside from the assignment, every single operation in this statement is promoting all your unsigned shorts to unsigned ints. Even the comparison. You might as well have just used unsigned from the start to save yourself a lot of typing:

constexpr auto n = 20u; // unsigned int

for (auto i = 2u; i &lt;= n; ++i)


And so on.

If you want to be technically correct, indexes should be std::size_t. But unsigned works well enough if you know you're not going any higher than 20. unsigned short is useless except for storage, because any operations you do on it get promoted.

printf("%llu", 2 * p[0][1]);


First, you're missing the std:: here.

But more importantly, you should be using C++ I/O:

std::cout &lt;&lt; (2 * p[0][1]);


Other than that, the most important element you're missing here would be comments, I'd say.