No18:Maximum path sum I

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
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值