どーも、みつおです。
総当たりで解く方法で実装した。
問題
以下の三角形の頂点から下まで移動するとき, その数値の和の最大値は23になる.
3
7 4
2 4 6
8 5 9 3この例では 3 + 7 + 4 + 9 = 23.
以下の三角形を頂点から下まで移動するとき, その最大の和を求めよ.
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注: ここではたかだか 16384 通りのルートしかないので, すべてのパターンを試すこともできる. Problem 67 は同じ問題だが100行あるので, 総当りでは解けない. もっと賢い方法が必要である.
出典:Problem18
解答
読み込みデータは「data.txt」を参照してね。
using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace Problem18 { class Program { static void Main(string[] args) { Console.WriteLine(Solve()); Console.ReadLine(); } private static long Solve() { long ret = 0; //ファイルを読み込み List<string> data = ReadFile(@"C:\Work\プロジェクトオイラー\問題18\data.txt"); //数値に変換したリストを作成 List<List<long>> lines = ConvertData(data); //頂点から最下点までたどった最大値を取得 ret = MaxNum(lines); return ret; } private static List<string> ReadFile(string filepath) { List<string> ret = new List<string>(); //読み込みファイルを開く using (StreamReader file = new StreamReader(filepath)) { string line = ""; //最終行が空になるまで読み込み while ((line = file.ReadLine()) != null) { //データを格納 ret.Add(line); } } return ret; } private static List<List<long>> ConvertData(List<string> data) { List<List<long>> ret = new List<List<long>>(); //最終行までループ foreach (var tmp in data) { List<long> linedata = new List<long>(); //行データを空白で分割 string[] tmp_line = tmp.Split(' '); //列のループ for (int i = 0; i < tmp_line.Count(); i++) { //数値に変換し、データを格納 linedata.Add(Convert.ToInt64(tmp_line[i])); } //行データを格納 ret.Add(linedata); } return ret; } static long MaxNum(List<List<long>> data) { long ret = 0; List<long> num = new List<long>(); //配列に変換 var datanum = data.ToArray(); //頂点を取得 num.Add(datanum[0][0]); //行数分ループ for (int i = 1; i < datanum.Count(); i++) { //一番右の合計を取得 long tmp = num[i - 1]; //配列に変換 var arraylist = num.ToArray(); //列数分ループ for (int j = 1; j < num.Count(); j++) { //左のデータを取得 long a = arraylist[j - 1]; //右のデータを取得 long b = arraylist[j]; //数値が大きくなる方に足しこむ if (a > b) num[j] = a + datanum[i][j]; else num[j] = b + datanum[i][j]; } //一番左側の合計値 num[0] = num[0] + datanum[i][0]; //一番右側の合計値 num.Add(tmp + datanum[i][datanum[i].Count - 1]); } //最大値を取得 ret = num.Max(); return ret; } } }
出力
1074