题目:传送门
分析
这个题真的没什么好说的,n太小了,直接 n3 暴力区间DP居然都能过。~~想了半天觉得线段树能做,后来没法查询就咕了。
d
p
[
i
]
[
j
]
表
示
从
i
到
j
全
部
合
并
成
1
个
后
的
数
值
dp[i][j]表示从i到j 全部合并成1个后的数值
dp[i][j]表示从i到j全部合并成1个后的数值 (全部合并)!
状态转移方程:
d
p
[
i
]
[
j
]
=
m
a
x
(
d
p
[
i
]
[
j
]
,
d
p
[
i
]
[
k
]
+
1
)
dp[i][j]=max(dp[i][j],dp[i][k]+1)
dp[i][j]=max(dp[i][j],dp[i][k]+1) (k为中间节点)
代码
#include<bits/stdc++.h>
using namespace std;
int n;
int f[250];
int dp[250][250];
inline int read()
{
int Num=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9') {Num=(Num<<1)+(Num<<3)+ch-'0'; ch=getchar();}
return Num*f;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
{
f[i]=read();
dp[i][i]=f[i];
}
int maxx=0;
for(int len=1;len<=n;len++)
for(int l=1;l<=n-len+1;l++)
{
int r=l+len-1;
for(int k=l;k<r;k++)
if(dp[l][k]==dp[k+1][r])
{
dp[l][r]=max(dp[l][r],dp[l][k]+1);
maxx=max(maxx,dp[l][r]);
}
}
printf("%d ",maxx);
return 0;
}