📅  最后修改于: 2023-12-03 15:42:12.636000             🧑  作者: Mango
本题考察的是动态规划技巧,需要找到一种有效的方法来解决问题。
有一个长度为 $n$ 的字符数组,已经按照字典序排好序了。现在给定一个字符 $x$,请找到插入 $x$ 后得到的新的排好序的字符数组。
要求插入 $x$ 后得到新的排序字符数组,首先可以找到一个规律:若将 $x$ 插入到 $a_i$ 和 $a_{i+1}$ 之间,那么得到的新的排序字符数组的前 $i$ 位和原始字符数组的前 $i$ 位是相同的。
假设 $dp_{i,j}$ 表示将 $x$ 插入到 $a_j$ 和 $a_{j+1}$ 之间得到新的排序字符数组的前 $i$ 位,求解 $dp_{n,j}$ 即可得到排序后的字符串数组。
对于 $dp_{i,j}$ 进行动态规划。显然,当 $i=1$ 时,$dp_{1,j}$ 的值即为插入 $x$ 后得到的新的排序字符数组的前一位。
当 $i>1$ 时,可以依据前面提到的规律,得到状态转移方程:
$$dp_{i,j}=dp_{i-1,j},\ \mathrm{if}\ x>a_i$$
$$dp_{i,j}=dp_{i-1,j-1},\ \mathrm{if}\ x<a_{j-1}$$
$$dp_{i,j}=dp_{i-1,j-1}+1,\ \mathrm{if}\ x \in [a_{j-1},a_i]$$
def sorted_array(a, x):
n = len(a)
dp = [[0] * (n+1) for _ in range(n+1)]
dp[1][0] = x
if x > a[0]:
dp[1][1] = a[0]
else:
dp[1][1] = x
dp[1][0] = a[0]
for i in range(2, n+2):
for j in range(1, i+1):
if j == 1:
if x >= a[0]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = dp[i-1][j]
elif j == i:
if x <= a[i-2]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = dp[i-1][j-2]
else:
if x > a[j-2]:
dp[i][j] = dp[i-1][j-1]
elif x < a[j-2]:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = dp[i-1][j-1] + 1
k = 0
for i in range(1, n+2):
if dp[n+1-i][i] != 0:
k = i
res = []
for i in range(1, k):
res.append(dp[k-i][i])
res.append(x)
for i in range(k, n+1):
res.append(dp[n+1-k][i])
return res