链接:
1312. 让字符串成为回文串的最少插入次数
题意:
如题
解:
动态规划,枚举回文串中点并递增回文串长度
初始状态若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])
实际代码:
#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
中所有字符都是小写字母。