Project Euler Problem 61
解法
入に下2桁,出に上2桁を指定したグラフを作ってDFSする.
DPにする必要は無かった.
実装(Visual Basic.NET)
自分の環境だと0.008秒で終了.
Imports System Imports System.IO Imports System.Text Imports System.Collections Imports System.Collections.Generic Imports System.Math Imports System.Diagnostics Public Structure Pair(Of T1 As IComparable(Of T1), T2 As IComparable(Of T2)) Public First As T1, Second As T2 Public Sub New(ByVal V1 As T1, ByVal V2 As T2) First = V1 : Second = V2 End Sub End Structure Module Module1 Public Answer As Integer Public Function P3(ByVal n As Integer) As Integer Return n * (n + 1) / 2 End Function Public Function P4(ByVal n As Integer) As Integer Return n * n End Function Public Function P5(ByVal n As Integer) As Integer Return n * (3 * n - 1) / 2 End Function Public Function P6(ByVal n As Integer) As Integer Return n * (2 * n - 1) End Function Public Function P7(ByVal n As Integer) As Integer Return n * (5 * n - 3) / 2 End Function Public Function P8(ByVal n As Integer) As Integer Return n * (3 * n - 2) End Function Public Graph(5, 99) As List(Of Pair(Of Integer, Integer)) Public Sub Make_Graph() Dim i As Integer, j As Integer For i = 0 To 5 For j = 0 To 99 Graph(i, j) = New List(Of Pair(Of Integer, Integer)) Next Next Dim V As Integer = 0 V = 0 For i = 0 To 9999 Dim t As Integer = P3(i) If t < 1000 Then Continue For If t > 9999 Then Exit For For j = 0 To 5 If V = j Then Continue For Graph(V, t \ 100).Add(New Pair(Of Integer, Integer)(j, t Mod 100)) Next Next V = 1 For i = 0 To 9999 Dim t As Integer = P4(i) If t < 1000 Then Continue For If t > 9999 Then Exit For For j = 0 To 5 If V = j Then Continue For Graph(V, t \ 100).Add(New Pair(Of Integer, Integer)(j, t Mod 100)) Next Next V = 2 For i = 0 To 9999 Dim t As Integer = P5(i) If t < 1000 Then Continue For If t > 9999 Then Exit For For j = 0 To 5 If V = j Then Continue For Graph(V, t \ 100).Add(New Pair(Of Integer, Integer)(j, t Mod 100)) Next Next V = 3 For i = 0 To 9999 Dim t As Integer = P6(i) If t < 1000 Then Continue For If t > 9999 Then Exit For For j = 0 To 5 If V = j Then Continue For Graph(V, t \ 100).Add(New Pair(Of Integer, Integer)(j, t Mod 100)) Next Next V = 4 For i = 0 To 9999 Dim t As Integer = P7(i) If t < 1000 Then Continue For If t > 9999 Then Exit For For j = 0 To 5 If V = j Then Continue For Graph(V, t \ 100).Add(New Pair(Of Integer, Integer)(j, t Mod 100)) Next Next V = 5 For i = 0 To 9999 Dim t As Integer = P8(i) If t < 1000 Then Continue For If t > 9999 Then Exit For For j = 0 To 5 If V = j Then Continue For Graph(V, t \ 100).Add(New Pair(Of Integer, Integer)(j, t Mod 100)) Next Next End Sub Public T(10) As Integer Public S As Integer Public Sub Solve(ByVal used As Integer, ByVal now1 As Integer, ByVal now2 As Integer, Optional ByVal V As Integer = 0) If used + 1 = 1 << 6 And now1 = 0 And now2 = S Then Console.WriteLine("{0}{1}{2}{3}{4}{5}", T(0), T(1), T(2), T(3), T(4), T(5)) Answer = T(0) + T(1) + T(2) + T(3) + T(4) + T(5) Answer *= 101 Return End If T(V) = now2 For j As Integer = 0 To Graph(now1, now2).Count - 1 If (used >> Graph(now1, now2)(j).First) And 1 Then Continue For Solve(used Or (1 << Graph(now1, now2)(j).First), Graph(now1, now2)(j).First, Graph(now1, now2)(j).Second, V + 1) Next End Sub Sub Main() Dim TimeCounter As New Stopwatch TimeCounter.Start() Answer = 0 Make_Graph() For i As Integer = 0 To 99 S = i Solve(0, 0, i) Next TimeCounter.Stop() Console.WriteLine("----") Console.WriteLine("Answer:{0}", Answer) Debug.WriteLine("Answer:{0}", Answer) Console.WriteLine("Calculate Time:{0}sec", TimeCounter.ElapsedMilliseconds / 1000) '----- Console.WriteLine() Console.WriteLine("Press Any Key.") 3: Console.ReadKey() End Sub End Module