1. 程式人生 > >Project Euler Problem 18

Project Euler Problem 18

By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.

3 7 4 2 4 6 8 5 9 3

That is, 3 + 7 + 4 + 9 = 23.

Find the maximum total from top to bottom of the triangle below:

75 95 64 17 47 82 18 35 87 10 20 04 82 47 65 19 01 23 75 03 34 88 02 77 73 07 63 67 99 65 04 28 06 16 70 92 41 41 26 56 83 40 80 70 33 41 48 72 33 47 32 37 16 94 29 53 71 44 65 25 43 91 52 97 51 14 70 11 33 28 77 73 17 78 39 68 17 57 91 71 52 38 17 14 91 43 58 50 27 29 48 63 66 04 68 89 53 67 30 73 16 69 87 40 31 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23

NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)

#include <iostream>
#include <cassert>
// assert() #include <cstdarg> // va_start() and va_end() #include <algorithm> // max() #include <ctime> // clock() using namespace std; int triangle4x4[4][4] = { {3}, {7,4}, {2,4,6}, {8,5,9,3} }; int triangle15x15[15+1][15+1] = { {75}, {95,64}, {17,47,82}, {18,
35,87,10}, {20,04,82,47,65}, {19,01,23,75,03,34}, {88,02,77,73,07,63,67}, {99,65,04,28,06,16,70,92}, {41,41,26,56,83,40,80,70,33}, {41,48,72,33,47,32,37,16,94,29}, {53,71,44,65,25,43,91,52,97,51,14}, {70,11,33,28,77,73,17,78,39,68,17,57}, {91,71,52,38,17,14,91,43,58,50,27,29,48}, {63,66,04,68,89,53,67,30,73,16,69,87,40,31}, {04,62,98,27,23, 9,70,98,73,93,38,53,60,04,23} }; class PE0018 { private: static const int MAX_SIZE = 15; int m_triangle[MAX_SIZE+1][MAX_SIZE]; int m_maxTotal; int m_routesSum; int m_routesStack[MAX_SIZE]; int m_routesRow[MAX_SIZE]; int m_routesCol[MAX_SIZE]; void debugPrintf(const char *format, ...); public: int getMaximumTotal(int dimension); void tryNext(int row, int col, int step, int n); }; // #define DEBUG int main() { clock_t start = clock(); PE0018 pe0018; assert(23 == pe0018.getMaximumTotal(4)); cout << "The maximum total from top to bottom of the triangle is " ; cout << pe0018.getMaximumTotal(15) << endl; clock_t finish = clock(); double duration=(double)(finish - start) / CLOCKS_PER_SEC; cout << "C/C++ application running time: " << duration << " seconds" << endl; return 0; } int PE0018::getMaximumTotal(int dimension) { m_maxTotal = 0; m_routesSum = 0; for(int row=0; row<dimension; row++) { for(int col=0; col<=row; col++) { if (4 == dimension) { m_triangle[row][col] = triangle4x4[row][col]; } else { m_triangle[row][col] = triangle15x15[row][col]; } } } tryNext(0, 0, 0, dimension); // parameters row, col and step starts from 0 return m_maxTotal; } void PE0018::tryNext(int row, int col, int step, int n) { m_routesStack[step] = m_triangle[row][col]; m_routesRow[step] = row; m_routesCol[step] = col; if (row >= col && row < n) { if (row+1 < n) { tryNext(row+1, col, step+1, n); } if (row+1<n && col+1<n) { tryNext(row+1, col+1, step+1, n); } } if (n-1 == row && n-1 == step) { m_routesSum++; int total = 0; for (int i=0; i<=step; i++) { total += m_routesStack[i]; debugPrintf("Step %2d : %2d (%2d, %2d)\n", i+1, m_routesStack[i], m_routesRow[i], m_routesCol[i]); } m_maxTotal = max(total, m_maxTotal); debugPrintf("==> m_routesSum = %d, m_maxTotal = %d\n\n", m_routesSum, m_maxTotal); } } void PE0018::debugPrintf(const char *format, ...) { #ifdef DEBUG va_list args; char buffer[512]; // it can change with the allowed max size va_start (args, format); (void)vsprintf (buffer, format, args); va_end(args); printf (buffer); #endif }