Самая "тяжёлая" операция здесь - это возведение в степень. Возведение в натуральную степень p питоновский рантайм выполняет за O(log p) умножений, и общая асимптотика выходит O(N × K × log(K)).
Можно изменить порядок итерации: внешний цикл - по n, внутренний - по k. Тогда для каждого n вычисляем q = 1 / (n + 1)², и v(n, k + 1) = v(n, k) × q × k / (k + 1), или можно заодно сэкономить умножение, отделив множитель k:
def doubles(maxk, maxn):
sum = 0
for n in range(1, maxn + 1):
q = 1 / ((n + 1) * (n + 1))
t = 1
for k in range(1, maxk + 1):
t *= q
sum += t / k
return sum
Здесь асимптотика понижается до O(N × K).
Вторая по сложности операция - это деление. Выполняется за экспоненту от количества цифр. Если памяти хватит (т.е. не миллиард итераций), то можно попробовать предварительно рассчитать q(n) и 1/k для всех n, k. Расчёт выполняется один раз, при этом видно замедление до печати первого результата, зато все остальные выдаются мгновенно.
qs = [1 / ((n + 1) * (n + 1)) for n in range(1, 10001)]
ks = [1 / k for k in range(1, 21)]
def doubles(maxk, maxn):
sum = 0
for n in range(1, maxn + 1):
q = qs[n-1]
t = 1
for k in range(1, maxk + 1):
t *= q
sum += t * ks[k-1]
return sum
Здесь асимптотика та же, но значительно (в разы) уменьшается её константный множитель.
Правда, тут стоит отметить, что вторая программа выдаёт расхождение с 14-го знака после точки, а первая считает в точности. Если это критично, то можно посмотреть в сторону типа decimal, правда, это замедлит вычисления и может аннулировать выигрыш от замены деления умножением. Хотя, можно обойтись без decimal, обычным int-ом, просто сдвинув десятичную точку на нужное число порядков.
Ещё можно взять эйлеровское обобщение ряда обратных квадратов для чётных степеней. Но там даётся сразу предел при n → ∞ (он вычисляется за константное время, и общая асимптотика будет O(K), т.к. останется только цикл по k), а для конечных n формулы нет.
https://ru.wikipedia.org/wiki/Ряд_обратных_квадратов