我正在尝试用Python语言解决this问题。请注意,只有第一次接吻才需要交替,任何由于第一次接吻而不是链中的一部分的接吻都可以很好地在第二个下一个人上拥抱,这是我想出的代码。这只是一个简单的数学计算,没有循环,没有迭代,什么都没有。但我仍然收到一条超时消息。有什么方法可以优化它吗?
import psyco
psyco.full()
testcase = int(raw_input())
for i in xrange(0,testcase):
n = int(raw_input())
if n%2:
m = n/2;
ans = 2 + 4*(2**m-1);
ans = ans%1000000007;
print ans
else:
m = n/2 - 1
ans = 2 + 2**(n/2) + 4*(2**m-1);
ans = ans%1000000007
print ans发布于 2012-09-02 18:38:14
这个问题的答案是一个非常简单的递归。对于F(1) = 2和F(n),我们有两个选择:
那么亲吻剩余客人的方式数就是F(n-1)
n = K,,那么亲吻剩馀客人的方式数就是2 ** k,其中k是公主没有被强迫亲吻的剩余客人的数量。因为她必须每隔一秒就亲吻剩下的客人,k = ceil((n - 1) / 2)把它们放在一起,我们就得到了F(n) = F(n - 1) + 2 ** ceil((n - 1) / 2)
我的尝试,包括采取一切mod 1000000007:
from math import ceil
def F(n):
m = 1000000007
a = 2
for i in range(2, n+1):
a = (a + pow(2, int(ceil((i - 1.0) / 2)), m)) % m
return a编辑:更新(更快,更难读!F(1e9)大约需要3分钟):
def F(n):
m = 1000000007
a = 2
z = 1
for i in xrange(2, n, 2):
z = (z * 2) % m
a = (a + z + z) % m
if (n & 1 == 0):
z = (z * 2) % m
a = (a + z) % m
return aEDIT 2:进一步思考后,我意识到上面的内容实际上只是:
F(n) = (1 + 1) + (2 + 2) + (4 + 4) + ... + (2 ** n/2 + 2 ** n/2)
= 2 * (1 + 2 + 4 + ... + 2 ** n/2)
= 2 * (2 ** (n/2 + 1) - 1)
= 2 ** (n/2 + 2) - 2但是如果n是偶数,那么最后一个2 ** n/2只出现一次,所以我们有:
def F(n):
m = 1000000007
z = pow(2, n/2, m)
if (n % 2 == 0):
return (z * 3 - 2) % m
else:
return (z * 4 - 2) % m它运行得更快!(受限于我认为是O(lg n)的pow(x, y, z)的速度?)
只是因为,这里有一句话:
def F(n):
return (pow(2, n/2, 1000000007) * (3 + n % 2) - 2) % 1000000007结果:
1 => 2
2 => 4
3 => 6
4 => 10
5 => 14
6 => 22
7 => 30
8 => 46
9 => 62
10 => 94
1e6 => 902893650
1e7 => 502879941
1e8 => 251151906
1e9 => 375000001发布于 2012-09-02 17:43:35
你的计算能力具有非常大的指数,如果结果在处理过程中没有减少,那么计算速度会非常慢。例如,10**10000000 % 11的朴素计算需要创建一个10000000位数并取模11。更好的方法是modular exponentiation,在每次乘法后减少模11,整数永远不会变大。
Python提供了内置的模幂运算。使用pow(a,b,c)计算(a**b) % c。
这是在假设你的算法是正确的基础上的,我没有验证过。
https://stackoverflow.com/questions/12234867
复制相似问题