最长回文序列
class Solution:
"""
@param s: the maximum length of s is 1000
@return: the longest palindromic subsequence's length
"""
def longestPalindromeSubseq(self, s):
# write your code here
if not s:
return 0
n=len(s)
res=[[0]*n for i in range(n)]
#init
for i in range(n):
res[i][i]=1 # length 1
if i>=1: #length 2
if s[i-1]==s[i]:
res[i-1][i]=2
else:
res[i-1][i]=1
for l in range(3,n+1):
for i in range(n-l+1):
j=i+l-1 # left:i right:j
res[i][j]=max(res[i+1][j],res[i][j-1])
if s[i]==s[j]:
res[i][j]=max(res[i][j],res[i+1][j-1]+2)
return res[0][n-1]
记忆化搜索方法:
class Solution:
"""
@param s: the maximum length of s is 1000
@return: the longest palindromic subsequence's length
"""
def longestPalindromeSubseq(self, s):
# write your code here
if not s:
return 0
n=len(s)
res=[[0]*n for _ in range(n)]
for i in range(n):
for j in range(n):
res[i][j]=-1
def compute(s,i,j):
if res[i][j]!=-1:
return ##important
if i==j:
res[i][j]=1
return
if j-i==1:
if s[i]==s[j]:
res[i][j]=2
else:
res[i][j]=1
return
compute(s,i+1,j)
compute(s,i,j-1)
compute(s,i+1,j-1)
res[i][j]=max(res[i+1][j],res[i][j-1])
if s[i]==s[j]:
res[i][j]=max(res[i][j],res[i+1][j-1]+2)
compute(s,0,n-1)
return res[0][n-1]
Coins in a line3
确定状态:
f[i][j]
f
[
i
]
[
j
]
为一方先手在面对
a[i],⋯,a[j]
a
[
i
]
,
⋯
,
a
[
j
]
这些数字时,能得到的最大的与对手的数字差:
个人理解,博弈就是先想一步,当前先手取数的时候,不仅要考虑取的这个数给自己当前带来的增益,也要考虑取走这个数后对手可能获得的增益。
def coins(lst):
n=len(lst)
f=[[0]*n for _ in range(n)]
for i in range(n):
f[i][i]=lst[i]
for length in range(2,n+1):
for i in range(n-length+1):
j=i+length-1
f[i][j]=max(lst[i]-f[i+1][j],lst[j]-f[i][j-1])
print (lst)
print ("f[{}][{}]=max({}-f[{}][{}],{}-f[{}][{}])".format(i,j,lst[i],i+1,j,lst[j],i,j-1))
print ("f[{}][{}]={}\n".format(i,j,f[i][j]))
return f[0][n-1]>=0
Scramble String
f[i][j][k]
f
[
i
]
[
j
]
[
k
]
表示S1能否通过替换转为T1,其中
- S1为从字符i开始的长度为k的字符串
- T1为从字符j开始的长度为k的字符串
class Solution:
"""
@param s1: A string
@param s2: Another string
@return: whether s2 is a scrambled string of s1
"""
def isScramble(self, s1, s2):
# write your code here
if not s1:
return True
n=len(s1)
f=[[[False]*(n+1) for _ in range(n)] for _ in range(n)]
for i in range(n):
for j in range(n):
if s1[i]==s2[j]:
f[i][j][1]=True
else:
f[i][j][1]=False
for k in range(2,n+1):
for i in range(n-k+1):
for j in range(n-k+1):
for w in range(1,k):
if f[i][j][w] and f[i+w][j+w][k-w]:
f[i][j][k]=True
break
if f[i][j+k-w][w] and f[i+w][j][k-w]:
f[i][j][k]=True
break
return f[0][0][n]
Burst Balloons
class Solution:
"""
@param nums: A list of integer
@return: An integer, maximum coins
"""
def maxCoins(self, nums):
# write your code here
if not nums:
return 0
n=len(nums)
nums.insert(0,1)
nums.append(1)
f=[[0]*(n+2) for _ in range(n+2)]
#f[i][j]=max(f[i][k]+f[k][j]+nums[i]*nums[j]*nums[k])i<k<j
for i in range(n+1):
f[i][i+1]=0
length=1
while length<=n:
i=0
while i+length+1<=n+1:
j=i+length+1
for k in range(i+1,j):
f[i][j]=max(f[i][k]+f[k][j]+nums[i]*nums[j]*nums[k],f[i][j])
i=i+1
length=length+1
return f[0][n+1]