gpt4 book ai didi

string - 翻转算法

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:30:23 25 4
gpt4 key购买 nike

我有一个字符串 s 包含不同类型的括号:()[] 。我怎样才能平衡这种类型的字符串与尽可能少的反转次数?我可以用任何其他支架替换任何支架。

例如:[)(] 的成本是 2,它变为 [()][](( 的成本是1、变成了[]()[(])不平衡。

一个更复杂的例子:)[)([)())] 可以在 4 个变化中变成 ([])[(())],但也可以分 3 步转为 [()(()())],这是使它平衡的最少修改次数。

我该如何解决这个问题?

最佳答案

我想到的第一个方法是 O(n^3)动态规划。

match(i, j)是为了制作 s[i] 必须进行的替换次数和 s[j]作为()[] .所以match(i, j)可以是 0 , 12 .

考虑 dp[i][j] = the minimum cost to balance the subsequence from i to j in your brackets array .现在您将定义 dp[i][i + 1]作为:

dp[i][i + 1] = match(i, i + 1)

现在一般规则是我们取 dp[i + 1][j - 1] + match(i, j) 之间的整体最小值和 min(dp[i][j], dp[i][p] + dp[p + 1][j])对于任何 i < p < j .显然,结果将保存在dp[1][n]中。 .有一个 C++ 解决方案(我也会在大约 15 分钟内上传一个 python 程序,当我完成它时 - python 不是那么强大:P)。

#include <iostream>
#include <string>
using namespace std;

int dp[100][100];
string s;
int n;

int match(char a, char b) {
if (a == '(' && b == ')') {
return 0;
}
if (a == '[' && b == ']') {
return 0;
}
if ((a == ')' || a == ']') && (b == '(' || b == '[')) {
return 2;
}
return 1;
}

int main() {
cin >> s;
n = s.length();
s = " " + s;
for (int i = 0; i <= n; ++i) {
for (int j = 0; j <= n; ++j) {
dp[i][j] = 0x3f3f3f3f;
}
}

for (int i = 1; i < n; ++i) {
dp[i][i + 1] = match(s[i], s[i + 1]);
}

for (int k = 3; k <= n; k += 2) {
for (int i = 1; i + k <= n; ++i) {
int j = i + k;
dp[i][j] = min(dp[i][j], dp[i + 1][j - 1] + match(s[i], s[j]));
for (int p = i + 1; p <= j; p += 2) {
dp[i][j] = min(dp[i][j], dp[i][p] + dp[p + 1][j]);
}
}
}
cout << dp[1][n] << '\n';
/*for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
cout << dp[i][j] << ' ';
}
cout << '\n';
}*/
return 0;
}

编辑:

给你 Python :)

s = input()
n = len(s)
inf = 0x3f3f3f3f

def match(x, y):
if x == '(' and y == ')':
return 0
if x == '[' and y == ']':
return 0
if (x == ')' or x == ']') and (y == '(' or y == '['):
return 2
return 1

# dp[i][j] = min. cost for balancing a[i], a[i + 1], ..., a[j]
dp = [[inf for j in range(n)] for i in range(n)]

for i in range(n - 1):
dp[i][i + 1] = match(s[i], s[i + 1])

for k in range(3, n, 2):
i = 0
while i + k < n:
j = i + k
dp[i][j] = min(dp[i][j], dp[i + 1][j - 1] + match(s[i], s[j]))
for p in range(i + 1, j, 2):
dp[i][j] = min(dp[i][j], dp[i][p] + dp[p + 1][j])
i += 1

print(dp[0][n - 1])
#for i in range(n):
# for j in range(n):
# print(dp[i][j], end = ' ')
# print()

关于string - 翻转算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40504845/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com