鉴于N" A" s和N" B" s。我们需要安排它们,如果A在B的左边,那么我们的解决方案会增加+1,而且我们需要保持在每个点上A的数量必须大于或等于B&#的数量39; S
现在我们需要计算这些2 * N字母表的这种排列,这样解决方案每次都等于K.
示例:假设N = 4且K = 2,则此处答案为6。
有6种可能的方式:
ABAAABBB
AABBAABB
AABAABBB
AAABABBB
AAABBABB
AAABBBAB
我的方法:我采用O(N * K)方法通过做暴力解决方案来解决这个问题。
设一个函数说F(last,Acount,K),然后检查我们是否可以放置A或B满足条件。但问题是N和K可能很大。
那么如何解决这个问题
答案 0 :(得分:3)
简短回答:Narayana numbers就是您所需要的。
我整个星期六都在研究你的问题。感谢您提出一个有趣的问题:)如果您有兴趣,我想告诉您解决问题的步骤。
你说你可以通过小输入来强制解决问题。对于算法问题,这可能会为您提供更好的解决方案(例如,如果您发现某些关系并猜测生成函数)。所以我也做了暴力(使用动态编程方法)并查看给定的数字。我第一次把它写到我的输出文件错误的方式(在一列中一个接一个的所有N的每个K)所以我没有找到一些美丽的关系。这就是为什么我没有找到答案的时间,并花了一些时间来获得更好的reccurent功能。
然后我试图将其推断为非重新确认功能但失败了(我认为因为它不是最好的可能)。然而,这样做我发现Pascal三角形之间的关系(对称性)然后以三角形方式将数字序列写入输出文件。
它看起来非常好,所以我只是用谷歌搜索了一些数字,并找到了Narayana数字的链接。
然后我试着推断出nonreccurent公式再没有成功(现在我可以检查它的正确性,因为序列公式已经知道):)所以这次我不知道Narayana数字的公式是如何给出的,尽管公式似乎很简单如果你有兴趣,你可以搜索更多。我希望我更深入,但我害怕花费整个假期:)
Here my brute force solution #1 and better reccurent solution #2。并且here the outputs我有一个三角形的方式(自动换行使它变丑,所以要小心)。 另外,感谢DavidEisenstat以正确的方式对您的问题发表评论。我检查了该链接,但没有进一步谷歌搜索找到解决方案。虽然这是回答问题的最短路径。
更新我没有提供快速计算组合的实现。有不同的方法可以在互联网上找到它,包括它的实现。计算的复杂性将是O(N),因此您将传递执行时间限制。或者,如果您需要多次回答查询(具有不同的N和K),则可以预先计算从1到N模数(1e6 + 9)的每个数的阶乘,然后使用它们来计算与O(1)的组合。
答案 1 :(得分:1)
现在有一个剧透,让我扩展我的评论。
给定一个包含n (
和n )
的字符串,附加一个)
。恰好其以)
结尾的n + 1个旋转中的一个以长度为2n的括号表达式开头。这是证明加泰罗尼亚公式的一种方法
C(n) = (2n choose n) / (n + 1).
对于这个问题,我们只想计算k次出现()
的带括号的表达式。通过从n-1中选择k-1个位置来插入零件边界,n个元素到k非空零件的有序分区数是(n - 1) choose (k - 1)
。通过将n + 1分成k个非空部分,我们可以计算以(
开头的长度(2n + 1)字符串的数量,以)
结尾,并且具有n (
's和n + 1 )
和k ()
为
((n - 1) choose (k - 1)) (n choose (k - 1)).
在这些字符串中,恰好k个旋转会产生相同形式的字符串,因此除以k以获得正确括号的数字。 (没有旋转对称性,因为如果k> 1则k不能除n或n + 1.)最终答案是
((n - 1) choose (k - 1)) (n choose (k - 1)) / k.
要快速计算二项式系数,请将因子及其反函数以模数模数加到n的最大值。