首先注意你有每种颜色的块的数量是一个完整的红鲱鱼,因为10^100>ñ始终。所以每种颜色的块数实际上是无限的。
现在请注意,在每个位置p
(如果存在有效配置,不会留下空格等)必须阻止颜色,c
。这个区块有说谎的方式len[c]
,所以它仍然在这个位置上,p
。
我的想法是尝试在固定位置(N/2
因为它半部的范围内)的所有可能的颜色和位置,然后对每一种情况下,存在该固定颜色块之后这个固定的彩色块和a
之前b
细胞。因此,如果我们定义一个函数ways(i)
,该函数返回平铺i
单元格的路数(使用ways(0)=1
)。那么在一个位置上用固定颜色块平铺多个单元格的方法的数量是ways(b)*ways(a)
。添加所有可能的配置会得到ways(i)
的答案。
现在我选择的固定位置是N/2
,因为这样可以将范围减半,最多可以将范围减半ceil(log(N))
次。现在,因为你正在移动约N/2
你将不得不计算从N/2-750
到N/2-750
,其中750
是最大长度块可以有块。所以你将不得不计算大约750*ceil(log(N))
(多一点因为方差)长度才能得到最终答案。
所以为了让你有memoisation要通过良好的表现,因为这本质上是一种递归算法。
所以使用Python(因为我懒,不想写一个大数目类):
T = int(raw_input())
for case in xrange(T):
#read in the data
C = int(raw_input())
lengths = map(int, raw_input().split())
minlength = min(lengths)
n = int(raw_input())
#setup memoisation, note all lengths less than the minimum length are
#set to 0 as the algorithm needs this
memoise = {}
memoise[0] = 1
for length in xrange(1, minlength):
memoise[length] = 0
def solve(n):
global memoise
if n in memoise:
return memoise[n]
ans = 0
for i in xrange(C):
if lengths[i] > n:
continue
if lengths[i] == n:
ans += 1
ans %= 100000007
continue
for j in xrange(0, lengths[i]):
b = n/2-lengths[i]+j
a = n-(n/2+j)
if b < 0 or a < 0:
continue
ans += solve(b)*solve(a)
ans %= 100000007
memoise[n] = ans
return memoise[n]
solve(n)
print "Case %d: %d" % (case+1, memoise[n])
注意我还没有彻底测试这一点,但我敢肯定它会满足20秒的时间限制,如果您将此算法转换为C++或其他。
EDIT:运行与N = 10^15
测试和块长度为750
我得到memoise
包含有关60000
元件,这意味着非查找solve(n)
位称为大约相同数量的时间。
我虽然有一个非常类似的解决方案。答案中有一些我不明白的地方。 '所以你将不得不计算大约750 * ceil(log(N))'。它不是'100 * 750^2 * log^2(N)'吗?请注意,在您的代码中,首先获取每种颜色,然后选取每个导致“100 * 750”的元素。另外,当在步骤i将N分成两部分时,不同块长度的数目将是'i * 750'(对于i> = 1)(对于第一步[i = 0],只有一个状态-N ),因此'log^2(N)* 750'。总的来说,这会导致'100 * 750^2 * 60^2〜200 * 10^9'(这不足以通过1最大测试) – Leonid 2010-10-30 09:14:04
实际上迭代的次数少于'60'。总体而言,这会导致“100 * 750^2 * 60”。通过'60000'元素的实验结果,我们可以用'60000'替换'750 * 60'。这导致“100 * 750 * 60000 = 4.5 * 10^9”。假设MOD(相当复杂的操作)将成为CPU的瓶颈,假设每秒大约100 * 10^6次迭代,最大测试时间可能需要大约30秒。 – Leonid 2010-10-30 09:29:49
我承认自己有点错过了,我的意思是你只需要计算'memoise'散列图中的'O(750 * log(N))'元素。运行时间约为'O(750 * 100 * 750 * log(N))'。现在考虑它有点慢... – JPvdMerwe 2010-10-30 09:34:48