思路
- 设dp[i][j]为【i,j】区间合并后的长度,a[i][j]为区间[i,j]合并后区间的值
- 分析:如果两个相邻区间能合并,必须要区间长度都为1,并且区间的值一样,否则不能合并
- 状态转移方程:dp[i][j]=min(dp[i][k]+dp[k+1][j]),在过程中判断一下[i,k]和[k+1,j]能不能合并,如果能就合并
代码
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int manx=1e3+5;
typedef long long ll;
ll dp[manx][manx],a[manx][manx];
int main()
{
ll n;
cin >> n;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
dp[i][j]=j-i+1;
for(int i=1;i<=n;i++)
cin >> a[i][i],dp[i][i]=1;
for(int len=2;len<=n;len++)
for(int l=1;l+len-1<=n;l++)
{
int r=l+len-1;
for(int k=l;k<r;k++){
dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]);
if(dp[l][k]==1&&dp[k+1][r]==1&&a[l][k]==a[k+1][r])
dp[l][r]=1,a[l][r]=a[l][k]+1;
}
}
printf("%lld",dp[1][n]);
return 0;
}