前言:在網上看到一道360的秋招真題,題目如下:
仔細讀題後發現這是一道求解最長公共子串行的問題,最好使用動態規劃演算法。
小b坐火車,從起點到終點的車站序列已知,期間他睡了兩覺,到終點的時候還在睡,也就是說中間他醒了兩次,這兩次清醒的時間,有兩個車站子串行,現在讓我們分析這兩段路是去的時候看到的,還是回來的時候看到的,來回都能看到,還是說壓根不存在。
一共有四種結果:
forward
backward
invalid
both
首先將兩個子串連線,判斷連線後的子串是否正好是與總串的最長公共子串行
若是,則forward驗證
然後反轉總串,再判斷連線後的子串是否正好是與總串的最長公共子串行
若是,則backward驗證
若都不是則不存在這樣的車站序列
1、最長公共子串行的結構(問題的最優子結構性質)
2、子問題的遞迴結構(建立遞迴關係)
由最優子結構性質可知,要找出x和y
的最長公共子串行可按以下方式遞迴地進行: (
1)當xm
=yn時,找出
xm-1和yn
-1的最長公共子串行。 (
2)當xm≠
yn時,必須解兩個子問題,找出
xm-1和y
的乙個最長公共子串行及x和
yn-1
的乙個最長公共子串行。這兩個公共子串行中
較長者即為x和
y的乙個最長公共子串行。
資料結構1:用c[i
][j]
記錄序列和的最長公共子串行的長度
資料結構2:用b[
i][j]
記錄當前序列和的**
(1)若c[i][j]由c[i-1][j-1]
得到,b[i][j] = 1
(2)若c[i][j]由c[i-1][j]得到,b[i][j] = 2
(3)若c[i][j]由c[i][j-1]得到,b[i][j] = 3
我的**:
# encoding :utf-8別人的**:def
lcs(k, l, slist, b):
if k == 0
or l == 0:
return
if b[k][l] == 1:
lcs(k - 1
, l - 1
, slist, b)
elif b[k][l] == 2:
lcs(k, l - 1
, slist, b)
else:
lcs(k - 1
, l, slist, b)
def
lcs2(k, l, sslist, b):
if k == 0
or l == 0:
return
if b[k][l] == 1:
lcs2(k - 1
, l - 1
, sslist, b)
elif b[k][l] == 2:
lcs2(k, l - 1
, sslist, b)
else:
lcs2(k - 1
, l, sslist, b)
while
1: fo = 0
ba = 0
s = raw_input()
a = raw_input()
b = raw_input()
ss = s[::-1]
slist = list(s)
slist.insert(0
, '0')
ablist = list(a + b)
ablist.insert(0
, '0')
sslist = list(ss)
sslist.insert(0
, '0')
c = [([0] * len(ablist)) for i in
range(len(slist))]
b = [([0] * len(ablist)) for i in
range(len(slist))]
cc = [([0] * len(ablist)) for i in
range(len(sslist))]
bb = [([0] * len(ablist)) for i in
range(len(sslist))]
# print c
# print slist
# print ablist
res =
for i in
range(1
, len(slist)):
for j in
range(1
, len(ablist)):
if slist[i] == ablist[j]:
c[i][j] = c[i - 1][j - 1] + 1
b[i][j] = 1
elif c[i - 1][j] > c[i][j - 1]:
c[i][j] = c[i - 1][j]
b[i][j] = 3
else:
c[i][j] = c[i][j - 1]
b[i][j] = 2
lcs(len(slist) - 1
, len(ablist) - 1
, slist, b)
print ablist
print res
if res[::-1] == ablist[1:]:
fo = 1
res =
for i in
range(1
, len(sslist)):
for j in
range(1
, len(ablist)):
if sslist[i] == ablist[j]:
cc[i][j] = cc[i - 1][j - 1] + 1
bb[i][j] = 1
elif cc[i - 1][j] > cc[i][j - 1]:
cc[i][j] = cc[i - 1][j]
bb[i][j] = 3
else:
cc[i][j] = cc[i][j - 1]
bb[i][j] = 2
lcs2(len(sslist) - 1
, len(ablist) - 1
, sslist, bb)
print res
if res[::-1] == ablist[1:]:
ba = 1
if fo == 1
and ba == 0:
"forward"
elif fo == 0
and ba == 1:
"backward"
elif fo == 1
and ba == 1:
"both"
else:
"invalid"
while看了人家的**才體會到什麼是差距,人家的**簡潔而又漂亮。這裡再惡補一下find函式是怎麼用的,發現沒有,有了find函式,根本就不需要寫求解最長公共子串行的函式了…1: a = raw_input()
b = raw_input()
c = raw_input()
e = len(b)
if (b in a) & (c in a):
bl = a.find(b)
if bl + e <= len(a) - 1:
if a.find(c, bl + e) > 0:
res = 1
else:
res = 0
else:
res = 0
else:
res = 0
d = a[::-1]
if (b in d) & (c in d):
bl = d.find(b)
if bl + e <= len(a) - 1:
if d.find(c, bl + e) > 0:
res += 2
else:
res += 0
else:
res += 0
else:
res += 0
if res == 0: print
'invalid'
if res == 1: print
'forward'
if res == 2: print
'backward'
if res == 3: print
'both'
簡介:find是字串型別的成員函式
函式原型:
s.find(str, pos_start, pos_end)
解釋:
返回值:如果查到:返回查詢的
第乙個出現的位置。
否則,返回-1。
python 動態規劃演算法
你有三枚硬幣,面值分別是a 2,5,7 每種硬幣足夠多,買一本書需要x 27元,如何用最少的硬幣組合正好付清,不需要對方找錢。1.確定狀態 假設最優解為k a1 a2 ak 1.1 最後一步 假設最優解為 27 ak 1.2 子問題 求27 ak最優解f x f x 2 1 f x 5 1 f x ...
Python 動態規劃演算法
假設你是乙個小偷,背乙個可裝4磅東西的揹包。可盜竊的商品有如下3件 音響,4磅,價值3000美元 膝上型電腦,3磅,價值2000美元 吉他,1磅,價值1500美元 為了讓盜竊的商品價值最高,你該選擇哪些商品?演算法 第9章動態規劃 w 0,4,3,1 商品的重量列表,w 0 佔位用 p 0,3000...
動態規劃演算法
一 動態規劃演算法原理 將待求解的問題分解成若干個相互聯絡的子問題,先求解子問題,然後從這些子問題的解得到原問題的解 對於重複出現的子問題,只在第一次遇到的時候對它進行求解,並把答案儲存起來。了不去求解相同的子問題,引入乙個陣列,把所有子問題的解存於該陣列中,這就是動態規劃所採用的基本方法。動態規劃...