题目链接:
dp思路:
①题目要求我们找到最少插入的字符数,让字符串变成回文词。因此,我们定义一个字符串p,它是字符串s的反转。我们找到 s、p的最长公共子序列,再用s长度减去 最长公共子序列就是答案。
②定义一个dp数组, 双重循环枚举 s、p 字符串。 当 s[i] == p[j] 时,dp[i][j] = dp[i-1][j-1] +1;当 s[i] != p[j] 时,由于 s、p 字符串现在枚举的字符是不相等的,因此我们只能选择它们两的其中一个。根据题意,我们要找到最长的公共子序列,dp[i][j] = max(dp[i-1][j], dp[i][j-1])。
③我们可以在读取字符串 s 的时候,从下标1开始读入,这样可以保证 dp[i-1][j-1] 在数组范围中。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
char s[N], p[N];
int dp[N][N];
int main(){
cin >> (s+1);
//从1开始获取s数组的有效长度
int n = strlen(s+1);
//将反转的s给p
int x = 0;
for(int i = n; i >= 1; i--){
p[++x] = s[i];
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(s[i] == p[j]){
dp[i][j] = dp[i-1][j-1]+1;
}
else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
cout <<n- dp[n][n] << endl;
return 0;
}