存储为字符串的数字的所有子序列的总和

时间:2017-01-07 17:59:57

标签: algorithm subsequence

查找存储为字符串模数(10 ^ 9)+7的数字的所有子序列的总和。该数字最多可以有N = 2 *(10 ^ 5)个数字。

示例 - 如果字符串为123,则其子序列为1,2,3,12,23,13,123。 Ans = 1 + 2 + 3 + 12 + 23 + 13 + 123 = 177.

3 个答案:

答案 0 :(得分:1)

T(i)i的前N个数字的总和,并将N[k]写为k的{​​{1}}个数字}。

然后:

N

这是因为T(0) = 0 T(i) = T(i-1) + T(i-1) * 10 + N[k] * (2**i) 的子序列的总和是T(i)的子序列加上T(i-1)的子序列的总和,每个子序列加上T(i-1)个数字。其中有k个,乘以10次通勤。

简化,将其放入代码中,并以算术模2**i进行算术,得出相对简单(并且在数字位数上的线性时间)解决方案:

k

输出:

def subsequences(n, k):
    total = 0
    pow2 = 1
    for i, ds in enumerate(n):
        total = (11 * total + pow2 * int(ds)) % k
        pow2 = (2 * pow2) % k
    return total

print subsequences('123', 10**9 + 7)

答案 1 :(得分:0)

我没有完全理解这个问题,但这里有一些想法。

对于n位数字串的子序列数是指数的,所以我们不能依赖强力。但我们可以通过动态编程来实现。假设F(i)表示其最后一个元素是字符串的第i个数字的所有子序列的总和。我们在O(i)中找到F(i + 1)的值,并在最后回答问题,我们输出求和F(1)+ ... + F(n)。

假设第i + 1位是j。然后

   F (i+1) =j+ (F (i)*10+ j)+(F (i-1)*10+ j)+...+(F (1)*10+ j)
               = (i+1)j+ 10 Sum F (z)  for 1<=z <= i

所以对于1≤i≤n,最终答案是ΣF(i)。

这可能仍然不够有效,因为大整数的总和已经是O(n),在每次迭代中我们有O(n)这样的求和并且有O(n)次迭代因此导致O(n ^ 3) ,这不是很好,但比指数更好。

答案 2 :(得分:0)

谢谢Paul Hankin。你的解释非常好。虽然我后来发现了算法。这就是我做的。方法是一样的。

static int mod = 1000000007;
public static long solve(String s) {
    long ans = 0;
    int n = s.length();
    for(int i=0; i<n; i++) {
        ans += (((Character.getNumericValue(s.charAt(i))*pow(11, n-i-1, mod))%mod)*pow(2, i, mod))%mod;
        ans %= mod;
    }
    return ans;
}