序列DP P375

这道题目,看一眼就知道是一个DP,但是状态搞错了,然后就写了好久,都没有写出来,看了一下题解,瞬间恍然大悟,隔了一天再去写,一下子就写出来了。

原因:我把状态想简单了,应该是dp[i][j] 对应i  到  j   的最小数值,

但是我是想用dp[i][0] 就去代表从1   到  i   的最小数值,状态没有跟上来,而且最近这种dp没有怎么做,就忘了。

错误:

class Solution:
    def getMoneyAmount(self, n: int) -> int:
        dp = [[0,0] for i in range(n+1)]
        if n == 1: return  0
        if n == 2: return 1
        if n == 3: return 2
        dp[1][0] =0;dp[1][1] =0;dp[2][0]=1;dp[2][1]=1;dp[3][0]=2;dp[3][1]=1;
        dp[4][0] = 4
        dp[4][1] = 2
        for i in range(5,n+1):
            min1 = 999999999
            for j in range(2,i):
                left = dp[j-1][0]
                right = dp[i-j][0] + dp[i-j][1]*j
                if left > right or (left == right and dp[j-1][1]+1 > dp[i-j][1]+1):
                    num1 = left + j
                    num2 = dp[j-1][1]+1
                else:
                    num1 = right + j
                    num2 = dp[i-j][1]+1
                if min1 > num1 or (min1 == num1 and dp[i][1] <num2):
                    dp[i][0] = num1
                    dp[i][1] = num2
                    min1 = num1
                if i==16 and min1 == 33:
                    print(left)
                    print(right)
                    print(j)
                    break
        # print(dp)
        return  dp[n][0]

正确的
 

class Solution:
    def getMoneyAmount(self, n: int) -> int:
        dp = [[0 for i in range(n+1)] for  i in range(n+1)]
        # print(dp[1][1])
        for i in range(n,0,-1):
            for j in range(i,n):
                for k in range(i,j):
                    if   dp[i][j] ==0: dp[i][j] = k + max(dp[i][k-1],dp[k+1][j])
                    else: dp[i][j] = min(dp[i][j],k + max(dp[i][k-1],dp[k+1][j]))
                    # dp[i][j] = k + max(dp[i][ k - 1], dp[k + 1][j])
                if dp[i][n] == 0:   dp[i][n] = j+max(dp[i][j-1] , dp[j+1][n])
                else:dp[i][n] = min(dp[i][n], j + max(dp[i][j-1],dp[j+1][n]))

                # if i == 7:
                    # print(j)
                    # print(dp[i][n])
            # print(i)
            # print(dp[i][n])
        # print(dp[7][12])
        return dp[1][n]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值