[USACO16OPEN][区间DP] 262144 P

题面

和通常套路不太一样,这题 \(N \le 262144\),不可以通过枚举区间的方程转移出来。
实际上,我们通过合并最大可以得出 \(58\),这个 \(58\) 实际就是 \(18 + 40\)\(40\) 是显然的,但是 \(18\) 呢?
我们考虑合并的过程,实际与倍增过程类似,最多我们会合并 \(\log n\) 次,再看看数据范围:\(2^{18} = 262144\)
于是我们就有了代码中的方程。

代码:

# include <iostream>
# include <cstdio>
# define MAXN 60
# define MAXM 270000

int f[MAXM][MAXN]; // f[i][j] 以 i 为左端点,合并出 j 的答案
int a[MAXM];

int main(){
	int n, ans = 0;
	scanf("%d", &n);

	for(int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
		f[i][a[i]] = i+1;
	}

	for(int j = 2; j <= 58; j++){
		for(int i = 1; i <= n; i++){
			if(!f[i][j]){
				f[i][j] = f[f[i][j-1]][j-1];
			}

			if(f[i][j]){
				ans = std::max(ans, j);
			}
		}
	}

	printf("%d", ans);

	return 0;
}
posted @ 2020-08-30 09:11  ChPu437  阅读(110)  评论(0编辑  收藏  举报