[南海云课堂] [区间 DP] 最小值
题意
给定一个长度为
-
选择第
i 个元素a_i ,并且需要满足a_i=a_{i+1} 。 -
将
a_i 和a_{i+1} 替换成a_i+1 。
每次操作很显然会使数组的长度减少
思路
显然,序列可分为若干个区间,两个小区间也可以合成大区间。
再观察
那么区间的状态如何表示?结合题目,定义
之所以之关注剩下
显然,只记录
状态有了,转移方程便非常明显。
若满足:
则说明
区间
定义
易发现,如果
最终输出
时间复杂度:
正确性:由于
代码
#include<bits/stdc++.h>
using namespace std;
const int N=5e2+5;
int n,a[N],f[N][N],jl[N][N],g[N],ans;
int main(){
cin>>n;
for(int i=1; i<=n;i++){
scanf("%d",&a[i]);
f[i][i]=1;
jl[i][i]=a[i];
}
for(int len=2; len<=n;len++){
for(int i=1; i<=n-len+1;i++){
int j=i+len-1;
for(int k=i; k<=j;k++){
if(f[i][k]&&f[k+1][j]&&jl[i][k]==jl[k+1][j]){
f[i][j]=1;
jl[i][j]=jl[i][k]+1;
}
}
}
}
ans=n;
for(int i=1; i<=n;i++){
g[i]=i;
for(int j=1; j<=i;j++){
if(f[j][i]){
g[i]=min(g[i],g[j-1]+1);
}
}
}
cout<<g[n];
return 0;
}