动态规划(二)

最长序列型动态规划

Longest Increasing Subsequence

f ( i ) :以 n u m s [ i ] 为结尾的最长上升子序列的长度

f ( i ) = m a x j < i , n u m s [ j ] < n u m s [ i ] f ( j ) + 1

class Solution:
    """
    @param nums: An integer array
    @return: The length of LIS (longest increasing subsequence)
    """
    def longestIncreasingSubsequence(self, nums):
        # write your code here
        if not nums:
            return 0
        length=[1]*len(nums)

        for i in range(len(nums)):
            j=0
            while j<i:
                if nums[j]<nums[i]:
                    length[i]=max(length[j]+1,length[i])
                j=j+1

        return max(length)

Russian Doll Envolopes

先按一维排序,即先按长度排序

f ( i ) = max j < i l e n g t h j < l e n g t h i w i d t h j < l e n g t h i f ( j ) + 1

如果按长度从小到大,宽度从大到小,相当于求宽度的最长上升子序列。
时间复杂度为 O ( n 2 ) ,time exceeded。

class Solution:
    """
    @param: envelopes: a number of envelopes with widths and heights
    @return: the maximum number of envelopes
    """
    def maxEnvelopes(self, envelopes):
        # write your code here
        if not envelopes:
            return 0
        if not envelopes[0]:
            return 0
        envelopes=sorted(envelopes,key=lambda x:(x[0],x[1]))
        nums=[1]*len(envelopes)

        for i in range(len(nums)):
            j=0
            while j <i:
                # Ej能放到Ei里
                if envelopes[j][1]<envelopes[i][1] and envelopes[j][0]<envelopes[i][0]:
                    nums[i]=max(nums[j]+1,nums[i])
                j=j+1        
        return max(nums)

划分型动态规划

这里写图片描述
这里写图片描述

Perfect Squares

f ( i ) 表示 i 最少被分为几个完全平方数之和

f ( i ) = min 1 i j 2 n ( f ( i j j ) ) + 1

class Solution:
    """
    @param n: a positive integer
    @return: An integer
    """
    def numSquares(self, n):
        # write your code here
        if not n:
            return 0
        nums=[i for i in range(n+1)]
        for i in range(1,n+1):
            if i>=2:
                j=1
                while j*j<=i:
                    nums[i]=min(nums[i-j*j]+1,nums[i])
                    j=j+1

        return nums[-1]

palindrome partitioning

f ( i ) 记录 s [ 0 : i ] 最少划分为几个回文串(不包括 s [ i ]

f [ i ] = min s [ j : i ] is a palindrome j = 0 , , i 1 ( f [ j ] ) + 1

确定状态:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

如何判断回文串?
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

class Solution:
    """
    @param s: A string
    @return: An integer
    """
    def minCut(self, s):
        n=len(s)
        # write your code here
        if not s:
            return 0


        isPalin=[[0]*n for i in range(n)]
        #记录原始序列中所有回文串
        for t in range(n):
            #所有奇数回文串
            x=t
            y=t
            while x>=0 and y<=n-1:
                if s[x]==s[y]:
                    isPalin[x][y]=1
                    x=x-1
                    y=y+1
                else:
                    break


            #所有偶数回文串
            x=t
            y=t+1
            while x>=0 and y<=n-1:
                if s[x]==s[y]:
                    isPalin[x][y]=1
                    x=x-1
                    y=y+1
                else:
                    break

        state=[i for i in range(len(s)+1)]
        for i in range(1,len(s)+1):
            for j in range(i):
                if isPalin[j][i-1]:
                    state[i]=min(state[j]+1,state[i])

        return state[-1]-1

Copy books

f [ k ] [ i ] 记为第 k 个人最少需要多少时间抄完 i 本书:

f [ k ] [ i ] = min j = 0 , , i max ( f [ k 1 ] [ j ] , A [ j ] + + A [ i 1 ] )

j = i 表明第 k 个人不抄书。
这个题下标有点搞不清楚。。。

博弈型动态规划

Coins in a line

确定状态
f ( i ) 表示先手面对 i 个石子时是必胜还是必败:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

class Solution:
    """
    @param n: An integer
    @return: A boolean which equals to true if the first player will win
    """
    def firstWillWin(self, n):
        # write your code here

        res=[False]*(n+1)
        for i in range(1,n+1):
            if i<=2:
                res[i]=True
            else:
                if res[i-1]==1 and res[i-2]==1:
                    res[i]=False
                else:
                    res[i]=True

        return res[-1]

猜你喜欢

转载自blog.csdn.net/XindiOntheWay/article/details/81585477