这道题目,看一眼就知道是一个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]