文章目录
1.印章
此题采用动态规划(Dynamic Programming,DP)的方法求解,动态规划的三要素:最优子结构、边界和状态转移函数。
最优子结构:每个阶段的最优状态可以从之前某个阶段的某个或某些状态直接得到
边界:问题最小子子集的解(初始范围)
状态转移函数:从一个阶段向另一个阶段过度的具体形式,描述的是两个相邻子问题之间的关系(递推式)
参考博主
·设置状态:当前状态下的数据包含小A手里的印章数目、印章的种类数目,因此可以构建二维数组dp[i][j]来存储概率。令dp[i][j] = 小A手里的印章数目为i、印章的总种类数目为n时小A收集齐j种印章的概率。
#法1
n,m = map(int,input().split())
dp = [ [0 for i in range(25)] for j in range(25)]
for i in range(1,m+1):
for j in range(1,n+1):
if i < j:
dp[i][j] = 0
elif j == 1:
dp[i][j] = (1/n) ** (i-1)
else:
dp[i][j] = ( dp[i-1][j]) * (j*1.0/n) + (dp[i-1][j-1]) * (n-j+1)*1.0/n
s = float(dp[m][n])
print('%.4f'%s)
#法2
n, m = map(int, input().split())
dp = [[0 for i in range(n + 1)] for i in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if (j > i):
dp[i][j] = 0
elif (j == 1):
dp[i][j] = pow(1 / n, i - 1)
else:
dp[i][j] = (dp[i - 1][j]) * (j * 1.0 / n) + (dp[i - 1][j - 1]) * ((n - j + 1) * 1.0 / n)
print("{:.4f}".format(dp[m][n]))
2. 拿金币
运行超时 70分
n = int(input())
x = [[0] * 0 for a in range(n)]
#print(x)
for i in range(n): #构建二维数组的方法
line = input().split()
for j in range(len(line)):
x[i].append(int(line[j]))
for i in range(n):
for j in range(n):
#第一种关系
if j == 0 and i == 0:
x[i][j] = x[i][j]
#第二种关系
elif j == 0:
x[i][j]=x[i-1][j]+x[i][j]
elif i == 0:
x[i][j]=x[i][j-1]+x[i][j]
else:
x[i][j] = max((x[i-1][j]+x[i][j]),(x[i][j]+x[i][j-1]))
print(x[n-1][n-1])
正确得分 100
n = int(input())
square = []
for i in range(n):
square.append(list(map(int, input().split())))
def dp_matrix(square):
# 处理传入的矩阵,使其变成动态规划的数组
for a in range(1, (n - 1) * 2 + 1):
if a < n:
start = 0
end = a + 1
else:
start = a - (n - 1)
end = n
for i in range(start, end):
j = a - i
if i == 0: # 判断此处位置是否在棋盘上边缘,如果是则只能从左侧格子移到此位置
square[i][j] = square[i][j] + square[i][j-1]
elif j == 0: # 判断此处位置是否在棋盘左边缘,如果是则只能从上方格子移到此位置
square[i][j] = square[i-1][j] + square[i][j]
else: # 如果不在期盼边缘,则可以从上方或左侧格子移到此位置,求出移到此位置的最大金币数
square[i][j] = square[i][j] + max(square[i-1][j], square[i][j-1])
return square[-1][-1]
print(dp_matrix(square))