NYOJ-37 回文字符串 —— LCS变形
2017-05-01 09:59
459 查看
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=37
题解:
一开始想从两边向中间添加字符,发现这样不是最优的。因为加入字符之后,这些原本存在的字符是离散的,所以就不能用顺序的方法去添加。
正确做法是将字符串逆过来,与原字符串求最大公共子序列。最大公共子序列即是不需要添加的字符序列,那么剩下的len-dp[len][len]就是需要添加进去的最少字符个数,使得原来的字符串刚好构成回文串。
代码如下:
题解:
一开始想从两边向中间添加字符,发现这样不是最优的。因为加入字符之后,这些原本存在的字符是离散的,所以就不能用顺序的方法去添加。
正确做法是将字符串逆过来,与原字符串求最大公共子序列。最大公共子序列即是不需要添加的字符序列,那么剩下的len-dp[len][len]就是需要添加进去的最少字符个数,使得原来的字符串刚好构成回文串。
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <vector> #include <map> #include <set> #include <queue> #include <sstream> #include <algorithm> using namespace std; #define pb push_back #define mp make_pair #define ms(a, b) memset((a), (b), sizeof(a)) #define eps 0.0000001 typedef long long LL; const int INF = 2e9; const LL LNF = 9e18; const int mod = 1e9+7; const int maxn = 1000+10; char s[maxn]; int dp[maxn][maxn]; void solve() { scanf("%s",s); int len = strlen(s); for(int i = 0; i<len; i++) { for(int j = 0; j<len; j++) { if(s[i]==s[len-1-j]) dp[i+1][j+1] = dp[i][j] + 1; else dp[i+1][j+1] = max(dp[i][j+1],dp[i+1][j]); } } printf("%d\n", len-dp[len][len]); } int main() { int T; scanf("%d",&T); while(T--){ ms(dp,0); solve(); } }
相关文章推荐
- nyoj 37 51nod oj 1092 回文字符串 【LCS变形】
- NYOJ - 37 - 回文字符串(LCS变形)
- NYOJ 37 回文字符串 (lcs最长公共子序列)
- nyoj 37 回文字符串(LCS)
- nyoj 37 回文字符串 【LCS】
- NYOJ37最大回文字符串(LCS)
- nyoj 37 回文字符串 【lcs&&dp】
- 【又见LCS】NYOJ-37 回文字符串
- NYOJ-37-回文字符串【LCS】
- nyoj--37 回文字符串(dp)
- NYOJ 37 回文字符串
- nyoj_37 回文字符串
- NYOJ 题目37 回文字符串(动态规划)
- nyoj 36 最长公共子序列 & nyoj 37 回文字符串
- NYOJ 37 回文字符串
- nyoj 回文字符串(LCS)
- nyoj-37-回文字符串
- nyoj 37题 回文字符串 (dp)
- nyoj_37 回文字符串
- NYOJ37 回文字符串(动态规划)