有一隻青蛙,有\(0, 1, \cdots, N - 1\)個荷葉。每一個荷葉上有權值\(s_i\)。c++
咱們考慮,選定了\(A\)、\(B\)後,青蛙的行走路線爲:
\[ \begin{eqnarray*} 0, A, A - B, A + (A - B), 2(A - B), \cdots, K(A - B), A + K(A - B) \end{eqnarray*} \]
咱們令\(C = A - B\):
\[ \begin{eqnarray*} 0, A, C, A + C, 2C, \cdots, KC, A + KC \end{eqnarray*} \]
顯然有:\(A + KC = N - 1\):
\[ \begin{eqnarray*} 0, N - 1 - KC, C, N - 1 - (K - 1)C, 2C, \cdots, KC, N - 1 \end{eqnarray*} \]
那麼當\(K\)、\(C\)肯定的時候,行走路線就已經肯定。
而且有一個限制條件爲\(KC < N\),那麼顯然枚舉\(K\)、\(C\)是\(O(nlogn)\)的。
而且咱們發現,當咱們固定\(C\),遞增\(K\)的時候,行走路線的變化是這樣的:
\[ \begin{eqnarray*} &&0, N - 1\\ &&0, N - 1 - C, C, N - 1\\ &&0, N - 1 - 2C, C, n - 1 - C, 2C, N - 1\\ \end{eqnarray*} \]
每次增長的是\(N - 1 - KC\)和\(KC\),這兩個點,只須要加上就行了,而且要注意判斷是否走到重複的點上了。spa
#include <bits/stdc++.h> using namespace std; #define ll long long #define N 100010 int n; ll s[N]; int used[N]; int main() { while (scanf("%d", &n) != EOF) { for (int i = 0; i < n; ++i) { scanf("%lld", s + i); } memset(used, 0, sizeof used); ll res = 0; for (int C = 1; C <= n; ++C) { ll tmp = 0; for (int k = 1; 1ll * k * C < n; ++k) { int a = k * C; int b = n - 1 - k * C; int A = b, B = b - C; if (A <= 0 || B <= 0) break; if (a < 0 || a >= n || b < 0 || b >= n || a == b) break; if (used[a] == C || used[b] == C) { break; } used[a] = C; used[b] = C; tmp += s[a]; tmp += s[b]; res = max(res, tmp); } } printf("%lld\n", res); } return 0; }