题目链接:https://www.luogu.com.cn/problem/P3147
题目大意:
思路:
我
们
用
f
[
i
]
[
j
]
表
示
从
位
置
j
开
始
合
并
成
一
个
数
i
的
最
远
位
置
。
怎
么
转
移
呢
?
我
们
只
考
虑
i
由
两
个
i
−
1
合
并
而
来
。
那
么
合
并
完
第
一
个
i
−
1
的
位
置
f
[
i
−
1
]
[
j
]
。
那
么
第
二
个
i
−
1
的
起
始
位
置
在
f
[
i
−
1
]
[
j
]
,
终
点
在
f
[
i
−
1
]
[
f
[
i
−
1
]
[
j
]
]
所
以
f
[
i
]
[
j
]
=
m
a
x
(
f
[
i
]
[
j
]
,
f
[
i
−
1
]
[
f
[
i
−
1
]
[
j
]
]
)
p
s
:
为
什
么
只
考
虑
由
i
−
1
合
并
而
来
。
如
果
能
够
由
更
小
的
数
合
并
,
那
么
一
定
先
合
并
成
了
i
−
1
。
p
s
:
i
的
最
大
值
为
什
么
为
58
。
如
果
全
部
是
40
。
最
多
合
并
成
40
+
l
o
g
2
262144
=
58
。
\begin{array}{l} 我们用f[i][j]表示从位置j开始合并成一个数i的最远位置。怎么转移呢?\\\\ 我们只考虑i由两个i-1合并而来。那么合并完第一个i-1的位置f[i-1][j]。\\\\ 那么第二个i-1的起始位置在f[i-1][j],终点在f[i-1][f[i-1][j]]\\\\ 所以f[i][j]=max(f[i][j], f[i-1][f[i-1][j]])\\\\ ps:为什么只考虑由i-1合并而来。如果能够由更小的数合并,那么一定先合并成了i-1。\\\\ ps:i的最大值为什么为58。如果全部是40。最多合并成40+log_{2}^{262144}=58。 \end{array}
我们用f[i][j]表示从位置j开始合并成一个数i的最远位置。怎么转移呢?我们只考虑i由两个i−1合并而来。那么合并完第一个i−1的位置f[i−1][j]。那么第二个i−1的起始位置在f[i−1][j],终点在f[i−1][f[i−1][j]]所以f[i][j]=max(f[i][j],f[i−1][f[i−1][j]])ps:为什么只考虑由i−1合并而来。如果能够由更小的数合并,那么一定先合并成了i−1。ps:i的最大值为什么为58。如果全部是40。最多合并成40+log2262144=58。
#include <bits/stdc++.h>
#define LL long long
using namespace std;
int f[60][270000];
int main() {
int n, x, ans=0; scanf("%d", &n);
for(int i=1; i<=n; i++){
scanf("%d", &x);
f[x][i]=i+1;
}
for(int i=1; i<=58; i++){
for(int j=1; j<=n; j++){
f[i][j]=max(f[i][j], f[i-1][f[i-1][j]]);
if(f[i][j]){
ans=i;
}
}
}
cout<<ans<<endl;
return 0;
}