题解 P3146 【[USACO16OPEN]248】
看到楼上奇妙的状态我来补一个比较正常的……
我们可以用普通区间dp解:
f[i][j]表示区间 i-j 合并的最大值
转移:
若f[i][k]==f[k+1][j]-->f[i][j]=max(f[i][k]+1,f[i][j])
但要注意, 若f[i][k]!=f[k+1][j],那么无法进行转移
一开始想的是:f[i][j]=max(f[i][j],max(f[i][k],f[k+1][j]));
但实际上是不可行的,因为只有相邻的才能合并,而上面的转移不能保证最大值在区间i-j的一端
这样我们对每段区间(包括区间[i,i])取max即可
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=250;
int n,ans=0,f[N][N];
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d",&f[i][i]);
ans=max(ans,f[i][i]);
}
for (int i=n-1;i>=1;i--)
for (int j=i+1;j<=n;j++){
for (int k=i;k<j;k++)
if (f[i][k]==f[k+1][j])
f[i][j]=max(f[i][j],f[i][k]+1);
ans=max(ans,f[i][j]);
}
printf("%d",ans);
return 0;
}