问题链接:https://www.codechef.com/problems/STR
问题是:
Little John just had his first class in school. He was taught first 20
letters of English alphabet and was asked to make words from these
alphabets.
Since he doesn't know many dictionary words, he quickly finished this work
by making random strings from these alphabets.
Now while other kids are busy creating their words, John gets curious and
puts all the strings he created in a list and named it X.
He picks two indices 'i' and 'j' ( not necessarily distinct). He assigns A
as X[i] and B as X[j]. He then concatenates both the strings to create a new
string C ( = A + B ). He calls a string "super string" if that string
contains all the 20 letters of English alphabet he has just learnt,atleast
once.
Given the strings of the list, can you tell him how many such unordered
pairs (i,j) he can choose such that string C is a super string.
社论:https://discuss.codechef.com/questions/79843/str-editorial
我无法理解dp的逻辑。有人可以帮助我吗?
答案 0 :(得分:0)
为简单起见,假设我们使用了来自' a'的前6个字符。到了' f'而不是20个字符。 我们将每个字符串存储为6位,方法是为其包含的字符添加1个(例如," abc&#34的位掩码;可以是111000)。
字符串s的超级掩码满足以下条件:
s = 111000
的超级are是111000, 111001 ... 111111
。 让我们将x表示为最大可能s值的整数表示,其中63.请注意,对于字符串s:
s | x - s = x
(111000 | 000111 = 56 + 7)
作者建议的第一个解决方案是:假设您已经计算了i+1, i+2 ... x
数0 <= i <= x
的所有超级掩码的数量。 令bit(i,k)表示输入位掩码的第k个最低有效位(for i = "111000", bit(i, 2) = 0
)。最后,让dp [i]表示i的超级掩码数。该算法表明,
dp[i] = 1
)i'
是i(dp[i]++
)i'
的所有超级主题都是i(dp[i] += dp[i | bit(i, k)]
) 问题是此解决方案多次计算相同的超级主机。考虑i = 111000
时的情况,它会为111111
和{{计算超级掩码i' = 111001
1}}。你需要找到一种方法来消除这些重复。
作者建议的最后一件事如下:设i'' = 111010
表示i的超级掩码数,这样i的最右边的j 0位都是零。例如dp[i][j]
,i = 111000
包括dp[i][j]
和111000
。使用这种方法,迭代111100
给出:
i = 111000
dp[i][0] = 111001, 111011, 111101, 111111
dp[i][1] = 111010, 111110
不幸的是,作者的文档非常糟糕,我无法理解他最终解决问题所使用的符号。不过,我希望这些解释足以理解逻辑。