题意
给你一个串s,每次可以花费1的代价删去一个子串,要求子串的每一位为同一个字符。
求删去整个串的最小代价。
分析
这是一道非常简单的区间\(DP\)问题,我们定义\(f[i][j]\)表示删去子串\([i,j]\)的最小花费。
就像合并石子一样,我们枚举中间的\(k\),k的范围是\(i\)~\(j\)。
为了方便解决问题,将k的定义域定义成一个半闭半合区间\([i,j)\),或者是\((i,j]\) 都可以,我们题解以\([i,j)\)为准。
决策考虑以下:
- 如果\(s[k]=s[j]\),那么说明当前的区间可以进行消除。
- 反之,则不能消除。
那么状态转移方程就是:\(f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+1-(s[k]=s[j]))\)。
ac代码
#include <bits/stdc++.h>
#define N 505
#define inf 0x3f3f3f3f
using namespace std;
char s[N];
int f[N][N];
int len;
int main() {
scanf("%d%s", &len, s);
for (int i = 0; i < len; i ++) f[i][i] = 1;
for (int i = 1; i < len; i ++)
for (int j = 0; j < i; j ++) {
f[j][i] = inf;
for (int k = j; k < i; k ++)
f[j][i] = min(f[j][i], f[j][k] + f[k + 1][i - 1] + 1 - (int)(s[k] == s[i]));
}
printf("%d\n",f[0][len - 1]);
return 0;
}