題目:兔子從第 1 格開始,每次在剩餘格子中跳往**美觀度最大**的格子(相同取前者),直到第 N 格,求經過格子美觀度之和。N 最大 200,000,需 O(N) 或 O(N log N) 算法。
正向模擬需反覆掃描「當前位置到末尾」的最大值,最壞 O(N²)。**關鍵觀察**:最終被訪問的格子序列,其美觀度**單調不增**(每次跳到剩餘最大值,後續最大值不可能比當前大)。
因此可從**右向左**掃描,維護「當前遇到的最大值」:
兔子策略等價於:選取序列中**從左到右的「嚴格遞增峰值」**(包含首元素)。逆向掃描正是在提取這些峰值。因為若某元素不是峰值,其右側必有 ≥ 它的元素,兔子會直接跳過它。
#include
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
if (!(cin >> N)) return 0;
vector a(N);
for (int i = 0; i < N; ++i) cin >> a[i];
long long sum = a[N-1];
long long curMax = a[N-1];
for (int i = N - 2; i >= 0; --i) {
if (a[i] > curMax) {
curMax = a[i];
sum += curMax;
}
}
cout << sum << "\n";
return 0;
}
import java.util.Scanner;
public class RainbowBridge {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
long[] a = new long[N];
for (int i = 0; i < N; i++) a[i] = sc.nextLong();
long sum = a[N-1];
long curMax = a[N-1];
for (int i = N-2; i >= 0; i--) {
if (a[i] > curMax) {
curMax = a[i];
sum += curMax;
}
}
System.out.println(sum);
}
}
這一逆向貪心策略完美解決大規模數據下的彩虹橋問題。