Algorithm Google codejam亚太测试实践回合:括号顺序
我花了一天时间来解决这个问题,却找不到一个解决方案来传递这个大数据集 问题 n个圆括号序列由n“(“s和n”)”s组成 现在,我们有了所有有效的n个括号序列。按字典顺序查找第k个最小序列 例如,以下是按字典顺序排列的所有有效的3个括号序列:Algorithm Google codejam亚太测试实践回合:括号顺序,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我花了一天时间来解决这个问题,却找不到一个解决方案来传递这个大数据集 问题 n个圆括号序列由n“(“s和n”)”s组成 现在,我们有了所有有效的n个括号序列。按字典顺序查找第k个最小序列 例如,以下是按字典顺序排列的所有有效的3个括号序列: ((())) (()()) (())() ()(()) ()()() 给定n和k,编写一个算法,以字典顺序给出第k个最小序列 对于大型数据集:1≤ N≤ 100和1≤ K≤ 10^18这个问题可以通过使用动态规划来解决 设dp[n][m]=如果有
((()))
(()())
(())()
()(())
()()()
给定n和k,编写一个算法,以字典顺序给出第k个最小序列
对于大型数据集:
1≤ N≤ 100和1≤ K≤ 10^18
这个问题可以通过使用动态规划来解决
- 设
dp[n][m]
=如果有n
开括号和m
闭括号,则可以创建的有效括号数
- 基本情况:
dp[0][a]=1(a>=0)
- 使用基本大小写填写矩阵:
dp[n][m]=dp[n-1][m]+(n
然后,我们可以慢慢地构建第k个括号
- 以a=n开括号开始和b=n闭括号开始,当前结果为空
while(k is not 0):
If number dp[a][b] >= k:
If (dp[a - 1][b] >= k) is true:
* Append an open bracket '(' to the current result
* Decrease a
Else:
//k is the number of previous smaller lexicographical parentheses
* Adjust value of k: `k -= dp[a -1][b]`,
* Append a close bracket ')'
* Decrease b
Else k is invalid
请注意,按字典顺序,开括号比闭括号小,所以我们总是先添加开括号
这个问题可以通过使用动态规划来解决
- 设
dp[n][m]
=如果有n
开括号和m
闭括号,则可以创建的有效括号数
- 基本情况:
dp[0][a]=1(a>=0)
- 使用基本大小写填写矩阵:
dp[n][m]=dp[n-1][m]+(n
然后,我们可以慢慢地构建第k个括号
- 以a=n开括号开始和b=n闭括号开始,当前结果为空
while(k is not 0):
If number dp[a][b] >= k:
If (dp[a - 1][b] >= k) is true:
* Append an open bracket '(' to the current result
* Decrease a
Else:
//k is the number of previous smaller lexicographical parentheses
* Adjust value of k: `k -= dp[a -1][b]`,
* Append a close bracket ')'
* Decrease b
Else k is invalid
请注意,按字典顺序,开括号比闭括号小,所以我们总是先添加开括号
让S=从n(和n)开始的任何有效括号序列
。
现在,任何有效的序列S都可以写成S=X+Y
where
X=有效前缀
即,如果在任何时间点从左到右遍历X,numberof'('>=numberof')”
Y=有效后缀
即,如果在任何时间点从右向左遍历Y,numberoff'('ncp),因此可能没有有效后缀*/
dp[nop][ncp]=i1+i2;
}
返回dp[nop][ncp];
}`
例如,n=3,即3(
和3)
现在,从一开始,X=empty_string
,因此
dp[3][3]
=使用3(
和3)
=3
(
和3)中有效后缀的数量Y
)
让S=n(和n)中的任何有效括号序列
。
现在,任何有效的序列S都可以写成S=X+Y
where
即,如果在任何时间点从左到右遍历X,X=有效前缀
numberof'('>=numberof')”
即,如果在任何时间点从右向左遍历Y,Y=有效后缀
例如,n=3,即3numberoff'('ncp),因此可能没有有效后缀*/ dp[nop][ncp]=i1+i2; } 返回dp[nop][ncp]; }`
和3(
现在,从一开始,X=empty_string,因此)
=使用3dp[3][3]
和3(
)
=来自3
和3(
那么你的问题是什么?@WimOmbelets我猜,解决上述问题的算法是什么?WimOmbelets我猜,解决上述问题的算法填充有效括号的基本情况是什么?谢谢你的算法。我运行了它,它是正确的。但是dp[n][m]的含义是什么(如果我们有n-开括号的数量和m-闭括号的数量,那么可以创建有效括号的数量)这让我很困惑。如果n!=m,我们如何才能得到有效括号?我不太理解dp[n][m]的含义@Danny您可以理解,在放下一些开括号和一些闭括号之后,从左括号中,您可以从这些括号中创建多少不同的有效配置。这就是为什么基本情况是dp[0][a],这意味着当你只有右括号时,你唯一能做的就是把它们都放下来。@Phamtrong这对我来说是有意义的。谢谢!@user2761431假设n=4,我们已经创建了这样的smt(()(”,因此,我们唯一能做的就是把它们都放在3个右括号中,这使得基本情况dp[0][3]=1:)填充有效括号数的基本情况是什么?谢谢你的算法。我运行了它,它是正确的。但是dp[n][m]的含义(如果我们有n-开括号数和m-闭括号数,则可以创建有效括号数)我不太明白dp[n][m]的意思。@Danny你可以理解,在放下一些开括号和闭括号后,从左括号中,你可以从这些括号中创建多少不同的有效配置。这就是为什么基本情况是dp[0][a],这意味着当你只有右括号时,你唯一能做的就是把它们都放下来。@Phamtrong这对我来说是有意义的。谢谢!@user2761431假设n=4,我们已经创建了这样的smt(()(”,因此,我们唯一能做的就是把它们都放在3个右括号中,这使得基本情况dp[0][3]=1:))的有效后缀
的数量Y
`calculate(nop,ncp) { if dp[nop][ncp] is not known { i1=calculate(nop-1,ncp); // Case 1: X= X + "(" i2=((nop<ncp)?calculate(nop,ncp-1):0); /*Case 2: X=X+ ")" if nop>=ncp, then after exhausting 1 ')' nop>ncp, therefore there can be no valid suffix*/ dp[nop][ncp]=i1+i2; } return dp[nop][ncp]; }`