链接:
题意:
如题
解:
动态规划,枚举回文串中点并递增回文串长度
初始状态若L==R
则单个字符为中点,需要添加0个字符成为回文串;若L+1==R
则如果S[L]==S[R]
则需要添加0个字符成为回文串,否则添加1个字符(选其一但是并不需要知道加的是那个)
状态转移:
如果S[L]!=S[R]
则DP[L][R] == min(dp[i + 1][j] + 1, dp[i][j - 1] + 1, dp[i + 1][j - 1]+1)
,但是dp[i + 1][j - 1]+1
其实至少 等价于其中之一,比如abc需要添加a和c变成acbca或cabac,那么ab和bc都为1,abc+2==(ab+1)+1==(bc+1)+1
;或者aac需要添加c,ac需要添加1,aa需要添加0,则aac+1==(aa)+1<=(ac+1)+1
如果s[L]==S[R]
,则DP[L][R]=min(DP[L][R],DP[L+1][R-1])
实际代码:
c++
#include<bits/stdc++.h>
using namespace std;
int minInsertions(string s)
{
int lg=s.size();
vector<vector<int>> dp(lg,vector<int>(lg,0x3f3f3f3f));
for(int i=0;i<lg;i++) dp[i][i]=0;
for(int t=1;t<lg;t++)//递增推导长度
{
for(int i=0;i+t<lg;i++)//递增起点
{
if(t==1)
{
if(s[i]==s[i+t]) dp[i][i+t]=0;
else dp[i][i+t]=1;
}
else
{
dp[i][i+t]=min(dp[i][i+t-1]+1,dp[i+1][i+t]+1);
if(s[i]==s[i+t]) dp[i][i+t]=min(dp[i][i+t],dp[i+1][i+t-1]);
}
}
}
return dp[0][lg-1];
}
int main()
{
string s;cin>>s;
int ans=minInsertions(s);
cout<<ans<<endl;
return 0;
}
限制:
1 <= s.length <= 500
s
中所有字符都是小写字母。