【发布时间】:2016-08-25 20:37:15
【问题描述】:
几个小时以来,我一直在努力解决一个算法问题。
问题的(花哨的)陈述如下:
我们的花园只有一排花。您将获得字符串花园中该行的当前内容。花园中的每个字符代表一朵花。不同的字符代表不同的颜色。相同颜色的花看起来都一样。您可以按照自己喜欢的顺序重新排列花园中的花朵。 (正式地,你可以交换你花园里的任意两朵花,你可以任意多次这样做。)你也被赋予了一个与花园长度相同的字符串。你想将花园重新排列成一个新的字符串 G,它将满足以下条件:
相邻的两朵花不会有相同的颜色。形式上,对于每个有效的 i,G[i] 和 G[i + 1] 必须不同。 对于每个有效的 i,G[i] 不能等于 forbid[i]。 令 X 为满足上述所有条件的不同字符串 G 的数量。计算并返回数字(X 模 1, 000, 000, 007)。
举个例子说明一下:X("aaabbb", "cccccc") = 2 ("ababab" and "bababa")
我一直在尝试计算字符串中有多少个字母(在示例中为 'a'->3、'b'->4),然后递归地计算不同的可能性(如果有重复则跳过或封禁信)。这些方面的内容:
using Map = std::map < char, size_t > ;
Map hist;
std::string forbid;
size_t countRecursive(std::string s, size_t len)
{
if (len == 0)
return 1;
size_t curPos = s.size() ;
size_t count(0);
for (auto &p : hist) {
auto key = p.first;
if (hist[key] == 0) continue;
if (forbid[curPos] == key) continue;
if (curPos > 0 && s[curPos - 1] == key) continue;
hist[key]--;
count += countRecursive(s + key, len - 1);
hist[key]++;
}
return count;
}
hist 和 forbid 是先前初始化的。但是,这似乎是 n!并且由于 n 可以
我并不是真的在寻找一个完整的解决方案。只是,如果您对我应该如何解决问题有任何建议,我将非常感谢!
【问题讨论】:
-
您是在尝试计算此类安排的数量还是尝试生成它们?前者更容易。
-
我只是想数数,但我仍然无法想到一个好的(性能方面)解决方案:/
-
@m69 我不完全相信这是正确的答案。假设我有“abcdefghijklmno”(15 个字母)并且禁止字符串都是“z”。我要15个!组合和链接中提到的算法(据我所知)将通过所有这些
-
你的问题确实有禁止列表的额外条件。您可以使用链接中问题的想法来获得排列的总数,然后您需要找到禁止排列的数量并减去它们。
标签: string algorithm math combinatorics