区间dp很明显
定 义 d p [ i ] [ j ] 为 [ i , j ] 消 除 的 最 小 代 价 定义dp[i][j]为[i,j]消除的最小代价 定义dp[i][j]为[i,j]消除的最小代价
首 先 可 以 枚 举 一 个 断 点 k , d p [ i ] [ j ] = m i n ( d p [ i ] [ k ] + d p [ k + 1 ] [ j ] ) 首先可以枚举一个断点k,dp[i][j]=min(dp[i][k]+dp[k+1][j]) 首先可以枚举一个断点k,dp[i][j]=min(dp[i][k]+dp[k+1][j])
其 次 是 当 i 和 j 处 的 字 母 相 同 时 怎 么 转 移 其次是当i和j处的字母相同时怎么转移 其次是当i和j处的字母相同时怎么转移
可以直接 d p [ i ] [ j ] = d p [ i + 1 ] [ j − 1 ] 吗 dp[i][j]=dp[i+1][j-1]吗 dp[i][j]=dp[i+1][j−1]吗
我 卡 在 这 里 , 因 为 我 觉 得 [ i + 1 , j − 1 ] 如 果 不 是 一 个 回 文 怎 么 转 移 ? 我卡在这里,因为我觉得[i+1,j-1]如果不是一个回文怎么转移? 我卡在这里,因为我觉得[i+1,j−1]如果不是一个回文怎么转移?
确 实 [ i + 1 , j − 1 ] 可 能 由 若 干 个 回 文 拼 起 来 确实[i+1,j-1]可能由若干个回文拼起来 确实[i+1,j−1]可能由若干个回文拼起来
但 我 们 消 的 时 候 是 一 个 一 个 消 , 消 到 最 后 [ i + 1 , j − 1 ] 只 剩 一 个 回 文 但我们消的时候是一个一个消,消到最后[i+1,j-1]只剩一个回文 但我们消的时候是一个一个消,消到最后[i+1,j−1]只剩一个回文
这时把i和j接上去还是回文,就一起消除了
#include <bits/stdc++.h>
using namespace std;
int n,a[509],dp[509][509];
int main()
{
cin >> n;
memset(dp,127,sizeof(dp));
for(int i=1;i<=n;i++) cin >> a[i],dp[i][i]=1;
for(int i=2;i<=n;i++)
if( a[i]==a[i-1] ) dp[i-1][i]=1;
for(int l=2;l<=n;l++)
{
for(int i=1;i+l-1<=n;i++)
{
int j=i+l-1;
if( a[i]==a[j] ) dp[i][j]=min( dp[i][j],dp[i+1][j-1]);
for(int k=i;k<=j;k++)
dp[i][j]=min( dp[i][k]+dp[k+1][j],dp[i][j]);
}
}
cout << dp[1][n];
}