Python LeetCode(五)

不同的做法

优化

1. 546. Remove Boxes

这是一开始的做法,直接用DFS来做,显然TLE

class Solution(object):
    result = 0
    def recursive(self, boxes, cur):
        l = len(boxes)
        if l == 0:
            if cur > self.result:
                self.result = cur
            return
        elif l == 1:
            if cur + 1 > self.result:
                self.result = cur + 1
            return
        i = 0
        while i < l:
            if boxes[i] == boxes[i + 1]:
                j = i
                while j + 1 < l and boxes[j] == boxes[j + 1]:
                    j += 1
                self.recursive(boxes[:i] + boxes[j + 1:], cur + pow(j - i + 1, 2))
                i = j + 1
            else:
                self.recursive(boxes[:i] + boxes[i + 1:], cur + 1)
    def removeBoxes(self, boxes):
        """
        :type boxes: List[int]
        :rtype: int
        """
        self.recursive(boxes, 0)
        return self.result

接着在前面的基础上,进行了些加速-对出现次数较少的先进行消除,比如这种情况:[1,2,3,4,3,2,1]

import collections
class Solution(object):
    result = 0
    def resetDict(self, boxes):
        d = collections.defaultdict(int)
        l = len(boxes)
        i = 0
        while i < l:
            if i + 1 < l and boxes[i] == boxes[i + 1]:
                j = i
                while j + 1 < l and boxes[j] == boxes[j + 1]:
                    j += 1
                d[i] = j - i + 1
                i = j
            else:
                d[i] = 1
            i+=1
        return d
    def recursive(self, boxes, cur):
        l = len(boxes)
        if l == 0:
            if cur > self.result:
                self.result = cur
            return
        elif l == 1:
            if cur+1 > self.result:
                self.result = cur+1
            return
        d = self.resetDict(boxes)
        s = sorted(d.keys(), key=lambda x: d[x], reverse=True)
        if d[s[0]] == d[s[len(s)-1]]:
            a = collections.Counter()
            for x in boxes:
                a[x]+=1
            s = sorted(d.keys(), key=lambda x:a[boxes[x]])
        for i in s:
            self.recursive(boxes[:i] + boxes[i + d[i]:], cur+pow(d[i], 2))
    def removeBoxes(self, boxes):
        """
        :type boxes: List[int]
        :rtype: int
        """
        self.recursive(boxes, 0)
        return self.result

嗯,发现还是TLE,看了别人的答案才知道应该用DP+DFS来做。😄

首先它的状态表示:

dp[i][j][k] 代表着在区间[i, j]内,并且在 j 之后有 k 个颜色和 j 相同的方块,它能够得到的最大分数。比如在数组[1,2,2],它的dp[0][1][0] 的值为5,为什么是1呢,因为它只有两种颜色

接着状态转义方程:

d[i,j,k]=d[i,j−1,0]+(len[j]+k)**2,当前分数取决于之前一个颜色的分数加上消除新颜色的分数考虑到在 i 和 j 之间,可能存在 k 和 j(当前颜色)的颜色是相同的,那么我们得优先删除 k 到 j 之间的内容,使得 k 和 j 能够靠在一起消除,所以:d[i,j,k]=d[i,pos,len[j]+k]+d[pos+1,j−1,0]c[pos]==c[j]∧i≤pos<j

class Solution(object):
    def removeBoxes(self, boxes):
        """
        :type boxes: List[int]
        :rtype: int
        """
        self.color, self.length = [], []
        for box in boxes:
            if self.color and self.color[-1] == box:
                self.length[-1] += 1
            else:
                self.color.append(box)
                self.length.append(1)
        M, N = len(self.color), len(boxes)
        self.dp = [[[0] * N for x in range(M)] for y in range(M)]
        return self.solve(0, M - 1, 0)
    def solve(self, l, r, k):
        if l > r: return 0
        if self.dp[l][r][k]: return self.dp[l][r][k]
        points = self.solve(l, r - 1, 0) + (self.length[r] + k) ** 2
        for i in range(l, r):
            if self.color[i] == self.color[r]:
                points = max(points, self.solve(l, i, self.length[r] + k) + self.solve(i + 1, r - 1, 0))
        self.dp[l][r][k] = points
        return points

不知道怎么做

posted @ 2017-08-05 15:47  banananana  阅读(207)  评论(0)    收藏  举报