https://leetcode-cn.com/problems/maximum-points-you-can-obtain-from-cards/
class Solution(object):
def maxScore(self, cardPoints, k):
"""
:type cardPoints: List[int]
:type k: int
:rtype: int
"""
#方法一暴力尝试,全部用例超过时间范围:
def methodOne(cardPoints,k):
memory={}
#定义process函数
def process(cardPoints,k,left,right,cursum,tickes):
if memory.has_key((left,right)):
return memory[(left,right)]
if tickes>k:
memory[(left,right)]=cursum
return cursum #已经到k张了,不用再拿第k+1张
if left==right:
#已经只剩最后一张牌了
tickes+=1
memory[(left,right)]=cursum+cardPoints[left]
return cursum+cardPoints[left]
#拿左边
p1=process(cardPoints,k,left+1,right,cursum+cardPoints[left],tickes+1)
#拿右边
p2=process(cardPoints,k,left,right-1,cursum+cardPoints[right],tickes+1)
ans=max(p1,p2)
memory[(left,right)]=ans
return max(p1,p2)
return process(cardPoints,k,0,len(cardPoints)-1,0,1)
#return methodOne(cardPoints,k)
#方法一二 可以记忆化搜索加速dp,还是超出时间限制
#方法二,转换dp,看是否能够空间压缩,加速dp,上面暴力尝试,主要left,right两个可变参数,cursum填表,tickes其实可以通过left,right算出
def methodTwo(cardPoints,k):
#dp[i][j] [0...i] 和[j...len-1]的都拿的分数值
#最终结果是j-i=k-1的所有状态值中找最大值,
return
#方法三,变相求固定窗口len-k大小子数组最小的部分,总和减它们就是了 最后变成范围dp
def methodThree(cardPoints,k):
if not cardPoints or len(cardPoints)<k:
raise(Exception("input invalid"))
n=len(cardPoints)
left=0
right=n-k-1 #下标
fixLenSum=sum(cardPoints[0:right+1]) #固定len-k滑动窗口大小
allSum=fixLenSum #总累计大小
minTarget=fixLenSum
while right<len(cardPoints)-1:
fixLenSum-=cardPoints[right-n+k+1]
right+=1
fixLenSum+=cardPoints[right]
allSum+=cardPoints[right]
minTarget=min(fixLenSum,minTarget)
return allSum-minTarget
return methodThree(cardPoints,k)