POJ--2138(DP)
2014-12-23 21:25:05
思路:首先将所有字符串排序,然后计算出两两间的“距离”,所谓距离就是串a到串b需要加多少个字符,如果无论怎么加a都达不到b,那么距离为正无穷。然后沿着距离为1的边进行DP,找最长路。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <stack> 9 #include <queue> 10 #include <iostream> 11 #include <algorithm> 12 using namespace std; 13 #define lp (p << 1) 14 #define rp (p << 1|1) 15 #define getmid(l,r) (l + (r - l) / 2) 16 #define MP(a,b) make_pair(a,b) 17 typedef long long ll; 18 typedef unsigned long long ull; 19 const int INF = 1 << 30; 20 const int maxn = 100; 21 22 int n,ans,pos; 23 string D[1010]; 24 int dis[1010][1010]; 25 int dp[1010]; 26 27 void Cal(int a,int b){ 28 int l1 = D[a].size(),l2 = D[b].size(); 29 int p1 = 0,p2 = 0; 30 while(p1 < l1 && p2 < l2){ 31 if(D[a][p1] == D[b][p2]) p1++,p2++; 32 else p2++; 33 } 34 if(p1 < l1) dis[a][b] = INF; 35 else dis[a][b] = l2 - l1; 36 } 37 38 int Solve(int p,int s){ 39 if(dp[p]) 40 return dp[p]; 41 if(s > ans){ 42 ans = s; 43 pos = p; 44 } 45 int res = 0; 46 for(int i = p + 1; i <= n; ++i){ 47 if(dis[p][i] == 1){ 48 res = max(res,Solve(i,s + 1)); 49 } 50 } 51 return dp[p] = res + 1; 52 } 53 54 bool cmp(string a,string b){ 55 return a.size() < b.size(); 56 } 57 58 int main(){ 59 cin >> n >> D[0]; 60 for(int i = 1; i <= n; ++i) 61 cin >> D[i]; 62 sort(D + 1,D + n + 1,cmp); 63 for(int i = 1; i <= n; ++i){ 64 for(int j = 0; j < i; ++j) 65 Cal(j,i); 66 } 67 Solve(0,0); 68 cout << D[pos] << endl; 69 return 0; 70 }