题意:长为 n 的序列,每次可以删除一个回文子串,删除之后两边合并起来,问最少几次可以将序列删完。
dp[l][r] 表示[l, r]区间内最少次数,s[l] ==s[r]时,dp[l][r] = dp[l+1][r-1]。
#include<cstring>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[505][505];
int s[505];
int solve(int l, int r){
if(l == r) return 1;
if(l > r) return 0;
if(dp[l][r] > 0) return dp[l][r];
int ret = 505;
for(int i = l; i < r; i++){
ret = min(ret, solve(l, i)+solve(i+1, r));
}
if(s[l] == s[r])
ret = min(ret, max(1, solve(l+1, r-1)));
dp[l][r] = ret;
return ret;
}
int main(){
//freopen("a.txt", "r", stdin);
int n;
while(scanf("%d", &n) != EOF){
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; i++)
scanf("%d", &s[i]);
cout << solve(1, n) << endl;
}
return 0;
}