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 }

 

posted @ 2014-12-23 21:27  Naturain  阅读(163)  评论(0编辑  收藏  举报