标签:
这道题就是给你两个序列A,和B, 然后问你求出一个用最少的Ade子序列组成B的方法。。例如A = abc B = abccba, 那么就可以用两个A表示B, 一个是正的序列, 另外一个是负的序列。对于这个问题我们先做一个小小的转换,我们将A倒置变为A1,然后就是用递增的A和A1序列表示B,我们用dp[2][i][j]表示从A(A1)[i],B[j]开始最长一致序列的长度, 然后求解答案的时候可以使用贪心的方法解决,具体详见代码:
#include <cstdio> #include <algorithm> #include <cstring> #include <map> #include <vector> using namespace std; char s[2500], t[2500]; int lens, lent; int dp[2][2500][2500]; //s i,t j开始往后最长相等的序列 vector<pair<int, int> > res; int main() { scanf("%s%s", s, t); lens = strlen(s); lent = strlen(t); for(int i=lens-1; i>=0; i--) for(int j=lent-1; j>=0; j--) { if(s[i]==t[j]) dp[0][i][j] = dp[0][i+1][j+1]+1; if(s[lens-1-i] == t[j]) dp[1][i][j] = dp[1][i+1][j+1]+1; } int cur = 0; while(cur < lent) { int tp = 0; //从cur位置开始最长匹配串 pair<int, int> add; //当前最优答案 for(int i=0; i<lens; i++) { if(dp[0][i][cur] > tp) { tp = dp[0][i][cur]; add = make_pair(i+1, i+tp); } if(dp[1][i][cur] > tp) { tp = dp[1][i][cur]; //add = make_pair(i+tp, i+1); add = make_pair(lens-i, lens+1-i-tp); } } if(tp == 0) { printf("-1\n"); return 0; } res.push_back(add); cur += tp; } printf("%d\n", res.size()); for(int i=0; i<res.size(); i++) { printf("%d %d\n", res[i].first, res[i].second); } return 0; }
标签:
原文地址:http://www.cnblogs.com/xingxing1024/p/5119612.html