我遇到了一个问题,我必须为所有 i <打印总和2 P i mod 1000000007 / strong>其中 P i 是集合X <的 i 子集中的数字总和/强>点。
集合长度最高可达 100000 。
元素值的范围 [0,10 12 ] 。
这是问题的链接。 Problem Statement
除了Brute-Force之外,我找不到任何可以判定TLE的方法。
这是问题陈述
紫罗兰,克劳斯和桑德波德莱尔被奥拉夫伯爵给了他一项任务,让他们在获得财产时保持忙碌。他给了他们N个号码并要求他们每个人做以下事情:他要求Sunny制作这组数字的所有可能子集。 然后他让Klaus找出这样形成的每个子集中的数字之和。 最后,他要求Violet告诉他所有i的总和为2 P i ,其中P i 是第i个子集中的数字之和。
由于奥拉夫伯爵在听这么长的数字时会感到无聊,所以他被要求给他答案模数1000000007。
你可以帮助波德莱尔摆脱这种困境吗?
输入格式
第一行输入包含一个数字N,表示该组的大小。以下行将包含构成该集的N个数字。
输出格式
将答案打印在一行中。
输入约束
1≤N≤105
0≤a[i]≤10 12
这是我的解决方案:
import itertools # importing module
#initializing the sum variable which will store final answer
t=0
#Input, number of elements in array
n=input()
#Input the array
arr=map(int,raw_input().split())
#Traverse all the possible combinations and update the sum variable 't'.
for i in xrange(len(arr)+1):
for val in itertools.combinations(arr,i):
x=sum(val)
t=(t+2**x)%1000000007
#Print final answer
print t
这是在时间限制内传递所有测试用例的工作算法,但我没有得到它背后的逻辑。
from sys import stdin
mod = 10**9 + 7
n = int(stdin.readline())
ans = 1
a = map(int,stdin.readline().split())
for i in a:
j = pow(2,i,mod)
ans = (ans*(j+1))%mod
print ans
@版主,管理员等 在暂停此问题或标记关闭主题或关闭之前.... 请评论原因,以便我可以知道原因,如果可能的话,可以在任何其他StackExchange站点上重新编写或询问。 我首先将它发布在codegolf.stackexchange.com上,人们(主持人)建议我在这里发布它,因为它属于算法类别。
你可以在这里阅读。
Programming Puzzles and Code golf
谢谢
答案 0 :(得分:5)
您已获得一组数字X
,并被要求计算sum(2^sum(x for x in A) for A a subset of X)
。
设X
为集合{x[0], x[1], ..., x[n]}
,S[i]
为x[0]...x[i]
子集总和中2的幂的总和。也就是S[i] = sum(2^sum(x for x in A) for A a subset of x[0]...x[i]))
。
x[0]...x[i+1]
的子集可以是x[0]...x[i]
的子集,也可以是添加了x[0]...x[i]
的{{1}}的子集。
然后:
x[i+1]
这为我们提供了计算结果的线性时间方法:
S[i+1] = sum(2^sum(x for x in A) for A a subset of x[0]...x[i+1])
= sum(2^sum(x for x in A) for A a subset of x[0]...x[i])
+ sum(2^sum(x for x in A+{x[i+1]}) for A a subset of x[0]...x[i])
= sum(2^sum(x for x in A) for A a subset of x[0]...x[i])
+ sum(2^x[i+1] * 2^sum(x for x in A) for A a subset of x[0]...x[i])
= S[i]
+ 2^x[i+1] * S[i]