Абсолютно нет необходимости вычислять 3 xn ^ 3 значения косинуса.
Можно считать, что x ≤ y ≤ z.Следовательно, x может быть любым целым числом в диапазоне от 1 до n / 3.y может быть любым целым числом в диапазоне от x до (n - x) / 2. И z должно быть равно n - x - y.Это само по себе уменьшает количество троек (x, y, z), которое вы пробуете, с n ^ 3 до примерно n ^ 2 / 6.
Далее предположим, что вы нашли три числа с общим количеством 2.749.И вы попробуйте х с косинус (х) = 0,748.Любая сумма с этим x не может быть больше 2.748, так что вы можете отклонить x напрямуюНайдя одну хорошую сумму, вы можете отклонить множество значений x.
Чтобы сделать это более эффективным, вы сортируете значения x по максимальному и минимальному значениям косинуса (x), потому что это повышает вероятность того, что вы найдете высокий итог, который позволит вам удалить больше значений.
И вычисление cos (x) идет медленно, поэтому вы сохраняете значения в таблице.
Итак:
Set c[i] = cos (i) for 1 ≤ i ≤ n.
Set x[i] = integers 1 to n/3, sorted in descending order by value of c[i].
Set (bestx, besty, bestz) = (1, 1, n-2) and total = c[bestx] + c [besty] + c [bestz].
for x = elements of array x where c[x] + 2 ≥ bestTotal
for y = x to (n-x)/2
z = n - x - y
total = c[x] + c[]y] + c[z]
if total > bestTotal
(bestx, besty, bestz) = (x, y, z)
bestTotal = total
Вы можете улучшить это с небольшим количеством математики.Если сумма y + z постоянна, как здесь, где y + z = n - x, сумма cos (y) + cos (z) ограничена.Пусть P будет целым числом, ближайшим к (n - x) / 2pi, и пусть d = (n - x) - P * 2pi, тогда наибольшая возможная сумма cos (y) + cos (z) равна 2 * cos (d)./ 2).
Таким образом, для каждого x, 1 ≤ x ≤ n / 3, мы рассчитываем это значение d и cos (x) + 2 * cos (d / 2), сохраняем эти значения как максимальное общее значение, которое может быть достигнутос некоторым x, сортируйте x так, чтобы эти значения были в порядке убывания, и игнорируйте те x, где достижимая сумма меньше, чем лучшая сумма на данный момент.
Если n действительно большое (скажем, миллиард), то вы можете использовать алгоритм Евклида, чтобы быстро найти все целые числа y, близкие к 2k * pi + d, но это будет немного сложно.
for x in 1 to n/3
let s = n - x
let P = s / 2pi, rounded to the nearest integer
let d = (s - P * 2pi) / 2
let maxSum [x] = cos(x) + 2*cos(d)
Set x[i] = integers 1 to n/3, sorted in descending order by value of maxSum[i].
Set (bestx, besty, bestz) = (1, 1, n-2)
Set bestTotal = c[bestx] + c [besty] + c [bestz].
for x = elements of array x where maxSum[x] ≥ bestTotal
for y = x to (n-x)/2
z = n - x - y
total = c[x] + c[]y] + c[z]
if total > bestTotal
(bestx, besty, bestz) = (x, y, z)
bestTotal = total
PS.Я на самом деле пробовал это для некоторых значений N около 100 миллионов.Оказывается, я могу либо отсортировать массив, чтобы сначала попробовать самые многообещающие значения для x, что занимает много времени, но часто первое значение для x является единственным, которое проверяется.Или я могу использовать x = 1, 2, 3 и т. Д., Что означает, что будут испробованы несколько десятков значений для x, что быстрее, чем сортировка.