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)
我起初的想法。是只选取最大的那个。。。。这样就是贪婪法了。。结果也证明错了。
#!/usr/bin/python
#encoding=utf-8
import operator
import datetime
import os
###############������###################
def searchpath (a,li,gra,height=15):
now_row=a[1]
now_col=a[2]
nextinfo1=(gra[now_row+1][now_col+1]+a[0],now_row+1,now_col+1)
nextinfo2=(gra[now_row+1][now_col-1]+a[0],now_row+1,now_col-1)
for info_in in (nextinfo1,nextinfo2) :
if info_in[1]==height-1:
print info_in
return info_in[0]
else:
li.append(info_in)
li.sort(reverse=True)
nextinfo=li.pop(0)
print nextinfo
return searchpath(nextinfo,li,gra,height)
def calList (in_str):
lines=[ [ int(x) for x in line.split() if x.strip() ] for line in in_str.split('\n') ]
height,width=len(lines),len(lines[-1])
print height,width
empty_list=[[ 0 for x in xrange(2*width-1) ] for y in xrange(height)]
for row in xrange(height,0,-1):
indent=height-row
for col in xrange(indent,2*width-1-indent) :
i=col-indent
if not i%2:
print row-1,col,(i+1)/2,lines[row-1][(i+1)/2]
empty_list[row-1][col]=lines[row-1][(i+1)/2]
return empty_list
strgot="""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"""
lines=[ [ int(x) for x in line.split() if x.strip() ] for line in strgot.split('\n') ]
height,width=len(lines),len(lines[-1])
print height,width
empty_list=[[ 0 for x in xrange(2*width-1) ] for y in xrange(height)]
for row in xrange(height,0,-1):
indent=height-row
for col in xrange(indent,2*width-1-indent) :
i=col-indent
if not i%2:
print row-1,col,(i+1)/2,lines[row-1][(i+1)/2]
empty_list[row-1][col]=lines[row-1][(i+1)/2]
for innerlist in empty_list:
print innerlist
s_li=[]
print empty_list[0][14]
mxv=searchpath((75,0,14),s_li,empty_list,15)
print mxv
in_str="""3
7 4
2 4 6
8 5 9 3"""
"""
s_list=[]
gra=calList(in_str)
mxv=searchpath ((3,0,3),s_list,gra,height=4)
print mxv
"""
#print f_list
#print mxv
#(value,row,col)
#print lines
结果我为1064。却报错误了。。
....发现自己不会做了,Fuck了,艹了。。
今天04/16了差不过1个多月了。
过了一个月,我再看我的代码,我只想说,这是我写的代码吗?这是给人看的代码吗。。一点注释都没有
。。。。
。。一定要养成注释的习惯了。。。
然后讨论一下这个问题吧。
过了一个月,再看这个问题,感觉不是很难。
递归或者动态归划都可以做出来啊。
这里先写出递归的吧。动态归划明天再做。
#encoding=utf-8
import operator
import datetime
import os
def searchpath (a,li,gra,height=15):
"""
a 表示当前遍历到的元素
li 用于存储一个元素的列表
gra表示所有元素的列表
height表示gra的高度
"""
now_row=a[1]#现在的行号
now_col=a[2]#现在的列号
nextinfo1=(gra[now_row+1][now_col+1]+a[0],now_row+1,now_col+1)#下一行的右孩子
nextinfo2=(gra[now_row+1][now_col-1]+a[0],now_row+1,now_col-1)#左孩子
for info_in in (nextinfo1,nextinfo2) :
if info_in[1]==height-1:#如果行号表示最后一行
print info_in
return info_in[0]
else:#如果非最后一行,则添加到li中
li.append(info_in)
#对li降序排序,取到最大值
li.sort(reverse=True)
nextinfo=li.pop(0)
print nextinfo
return searchpath(nextinfo,li,gra,height)
def calList (in_str):
"""
作用:将字符串转换为二维列表
"""
lines=[ [ int(x) for x in line.split() if x.strip() ] for line in in_str.split('\n') ]#把输入的字符串转换为二维列表
height,width=len(lines),len(lines[-1])
print height,width
empty_list=[[ 0 for x in xrange(2*width-1) ] for y in xrange(height)]
for row in xrange(height,0,-1):
indent=height-row
for col in xrange(indent,2*width-1-indent) :
i=col-indent
if not i%2:
print row-1,col,(i+1)/2,lines[row-1][(i+1)/2]
empty_list[row-1][col]=lines[row-1][(i+1)/2]
return empty_list
#递归法
def recursive_path(search_ele,gra,session,height):
"""
search_ele 当前元素
gra 表示整个元素的列表
session 表示缓存
height 表示整个列表的高度
"""
now_row,now_col=search_ele[1],search_ele[2] #search_ele所有的行号,以及列号
if session[now_row][now_col]!=-1:#表示该元素有缓存
return session[now_row][now_col]
else:
#该元素还没有缓存
leftChild=(gra[now_row+1][now_col-1],now_row+1,now_col-1)#左孩子
rightChild=(gra[now_row+1][now_col+1],now_row+1,now_col+1)#右孩子
maxvalue=0
if now_row==height-2:#倒数第二行
maxvalue=max(leftChild[0],rightChild[0])+search_ele[0]
else:
maxvalue=max(recursive_path(leftChild,gra,session,height),recursive_path(rightChild,gra,session,height))+search_ele[0]
session[now_row][now_col]=maxvalue
return maxvalue
starttime=datetime.datetime.now()
strgot="""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"""
s_list=[]
gra=calList(strgot)
height,width=len(gra),len(gra[0])#高度,宽度
searchindex=gra[0].index(75)
session=[ [-1 for col in xrange(width) ] for row in xrange(height)]#缓存
mxv=recursive_path((75,0,searchindex),gra,session,height)
print mxv
endtime=datetime.datetime.now()
print (endtime-starttime)
输出的结果为:
动态规划法如下:
#encoding=utf-8
import operator
import datetime
import os
#动态规则法
def getmaxvalue_path(gra,height,width):
"""
对gra里的元素找到最大路径值,以及最大路径
height:gra的高度
width:gra的宽度
"""
maxvalue_path=[[ (0,[]) for col in xrange(width)] for row in xrange(height) ]#(0,[])表示的是最大路径值,以及路径
for row in xrange(height-1,-1,-1):
if row==height-1:#最后一行初始化
maxvalue_path[row]=[ (gra[row][col],[(row,col)]) for col in xrange(width)]
else:
for col in xrange(width):
if col==0:#第一列
temptuple=maxvalue_path[row+1][col+1]
elif col==width-1:#最后一列
temptuple=maxvalue_path[row+1][col-1]
else:#既不是第一列,也不是最后一列
temptuple=maxvalue_path[row+1][col-1]
temptuple2=maxvalue_path[row+1][col+1]
if temptuple2[0]>temptuple:
temptuple=temptuple2
path_list=temptuple[1][:]
path_list.insert(0,(row,col))
maxvalue_path[row][col]=(temptuple[0]+gra[row][col],path_list)
return maxvalue_path
def calList (in_str):
"""
作用:将字符串转换为二维列表
"""
lines=[ [ int(x) for x in line.split() if x.strip() ] for line in in_str.split('\n') ]#把输入的字符串转换为二维列表
height,width=len(lines),len(lines[-1])
#print height,width
empty_list=[[ 0 for x in xrange(2*width-1) ] for y in xrange(height)]
for row in xrange(height,0,-1):
indent=height-row
for col in xrange(indent,2*width-1-indent) :
i=col-indent
if not i%2:
#print row-1,col,(i+1)/2,lines[row-1][(i+1)/2]
empty_list[row-1][col]=lines[row-1][(i+1)/2]
return empty_list
starttime=datetime.datetime.now()
strgot="""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"""
s_list=[]
gra=calList(strgot)
height,width=len(gra),len(gra[0])#高度,宽度
searchindex=gra[0].index(75)
session=[ [-1 for col in xrange(width) ] for row in xrange(height)]#缓存
#mxv=getmaxvalue_path((75,0,searchindex),gra,session,height)
maxvalue_path=getmaxvalue_path(gra,height,width)
print maxvalue_path[0][searchindex]
endtime=datetime.datetime.now()
print (endtime-starttime)
但是有问题啊。
15 15
(794, [(0, 14), (1, 13), (2, 12), (3, 11), (4, 10), (5, 9), (6, 8), (7, 7), (8, 6), (9, 5), (10, 4), (11, 3), (12, 2), (13, 1), (14, 0)])
0:00:00.002000
为什么输出结果会这个样子呢?
========================================================================================
知道是哪里了if temptuple2[0]>temptuple:
temptuple=temptuple2
这里写错了。。一不小心就写错了。。
改为
if temptuple2[0]>temptuple[0]:
temptuple=temptuple2
就好了,
结果如下:
#encoding=utf-8
import operator
import datetime
import os
#动态规则法
def getmaxvalue_path(gra,height,width):
"""
对gra里的元素找到最大路径值,以及最大路径
height:gra的高度
width:gra的宽度
"""
maxvalue_path=[[ (0,[]) for col in xrange(width)] for row in xrange(height) ]#(0,[])表示的是最大路径值,以及路径
for row in xrange(height-1,-1,-1):
if row==height-1:#最后一行初始化
maxvalue_path[row]=[ (gra[row][col],[(row,col)]) for col in xrange(width)]
else:
for col in xrange(width):
if col==0:#第一列
temptuple=maxvalue_path[row+1][col+1]
elif col==width-1:#最后一列
temptuple=maxvalue_path[row+1][col-1]
else:#既不是第一列,也不是最后一列
temptuple=maxvalue_path[row+1][col-1]
temptuple2=maxvalue_path[row+1][col+1]
if temptuple2[0]>temptuple[0]:
temptuple=temptuple2
path_list=temptuple[1][:]
path_list.insert(0,(row,col))
maxvalue_path[row][col]=(temptuple[0]+gra[row][col],path_list)
return maxvalue_path
def calList (in_str):
"""
作用:将字符串转换为二维列表
"""
lines=[ [ int(x) for x in line.split() if x.strip() ] for line in in_str.split('\n') ]#把输入的字符串转换为二维列表
height,width=len(lines),len(lines[-1])
#print height,width
empty_list=[[ 0 for x in xrange(2*width-1) ] for y in xrange(height)]
for row in xrange(height,0,-1):
indent=height-row
for col in xrange(indent,2*width-1-indent) :
i=col-indent
if not i%2:
#print row-1,col,(i+1)/2,lines[row-1][(i+1)/2]
empty_list[row-1][col]=lines[row-1][(i+1)/2]
return empty_list
starttime=datetime.datetime.now()
strgot="""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"""
s_list=[]
gra=calList(strgot)
height,width=len(gra),len(gra[0])#高度,宽度
searchindex=gra[0].index(75)
session=[ [-1 for col in xrange(width) ] for row in xrange(height)]#缓存
#mxv=getmaxvalue_path((75,0,searchindex),gra,session,height)
maxvalue_path=getmaxvalue_path(gra,height,width)
print maxvalue_path[0][searchindex]
endtime=datetime.datetime.now()
print (endtime-starttime)
运行结果为:
(1074, [(0, 14), (1, 15), (2, 16), (3, 15), (4, 14), (5, 15), (6, 14), (7, 13), (8, 14), (9, 15), (10, 16), (11, 17), (12, 18), (13, 17), (14, 18)])
0:00:00.001000