Problem:
最短経路

図１に例示するように整数（0 以上 99 以下）をひしがたに並べます。このような、ひしがたを表すデータを読み込んで、一番上からスタートして一番下まで次のルールに従って進むとき、通過する整数の和の最大値を出力するプログラムを作成してください。

各ステップで、対角線上の左下か対角線上の右下に進むことができます。

例えば図1の例では、図2に示すように、7,3,8,7,5,7,8,3,7を選んで通ったとき、その和は最大の 55 （7+3+8+7+5+7+8+3+7=55） となります。

Input

入力例に示すように、カンマで区切られた整数の並びが、ひし形状に与えられます。各行に空白文字は含まれません。入力例は図１に対応しています。
データの行数は 100 行未満です。

Output

ルールに従って通過する整数の和の最大値を１行に出力します。

Sample Input

7
3,8
8,1,0
2,7,4,4
4,5,2,6,5
2,7,4,4
8,1,0
3,8
7

Sample Output

55

Solution in C# (judge verdict: Time Limit Exceeded)

using System;
using System.Linq;
class aoj
{
    static void Main()
    {
        int[][] a = new int[50][];
        int[][] b = new int[50][];
        int d = 0, f = 0, e, i, h, l, n = 0, p = 0;
        while (true)
        {
            int[] c = Console.ReadLine().Split(',').Select(int.Parse).ToArray();
            e = c.Length;
            if (e > d) { a[f] = c; f++; d = e; }
            else { b[0] = c;  break; }
        }
        for(i = 1; i < d-1; i++)
        {
            int[] c = Console.ReadLine().Split(',').Select(int.Parse).ToArray();
            b[i] = c;
        }
        int[,] g = new int[d,2];
        for ( i = 0; i < Math.Pow(2, d - 1); i++)
        {
            h = i;
            l = 0;
            bool[] k = new bool[d - 1];
            for(int j = d-2; j >=0; j--)
            {
                if(h>=Math.Pow(2,j)) { k[d-2-j] = true;h -= (int)Math.Pow(2,j); }
            }
            h = 0;
            l = 0;
            for(int j = 0; j < d; j++)
            {
                l += a[j][h];
                if (j!=d-1&&k[j])
                    h++;
            }
            if (l > g[h,0]) g[h,0] = l;
        }
        int[][] m = new int[d - 1][];
        for(i = d - 2; i >= 0; i--)
        {
            m[n] = b[i];
            n++;
        }
        for (i = 0; i < Math.Pow(2, d - 2); i++)
        {
            h = i;
            l = 0;
            bool[] k = new bool[d - 2];
            for (int j = d - 3; j >= 0; j--)
            {
                if (h >= Math.Pow(2, j)) { k[j] = true; h -= (int)Math.Pow(2, j); }
            }
            h = 0;
            for (int j = 0; j < d - 1; j++)
            {
                l += m[j][h];
                if (j!=d-2&&k[j])
                    h++;
            }
            if (l > g[h,1]) g[h,1] = l;
        }
        for(i = 0; i < d-1; i++)
        {
            for(int j = 0; j < 2; j++)
            {
                int o = g[i,1] + g[i + j,0];
                if (o > p) p=o;
            }
        }
        Console.WriteLine(p);
    }
}