字符串DP
【题意】
给定n个字符串,求最长的单词链。两个单词能连起来,当且仅当这两个串只相差一个字符(不考虑顺序),且后者比前者长1。
【题解】
DP水,字符串内排序+TRIE。
【代码】
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
const int maxn=10010;
struct node
{
node *ch[26];
int id;
node()
{
id=-1;
for (int i=0;i<26;i++)
ch[i]=NULL;
}
};
node* root=new node();
string s[maxn];
int dp[maxn],p[maxn];
int n,ans;
void ins(string s,int x)
{
int len=s.size();
node* now=root;
for (int i=0;i<len;i++)
{
int k=s[i]-'a';
if (now->ch[k]==0)
now->ch[k]=new node();
now=now->ch[k];
}
now->id=x;
}
int find(string s)
{
int len=s.size();
node* now=root;
for (int i=0;i<len;i++)
{
int k=s[i]-'a';
if (now->ch[k]!=0)
now=now->ch[k];
else
return -1;
}
return now->id;
}
void print(int x)
{
if (x==-1) return;
print(p[x]);
cout << s[x] << endl;
}
bool cmp(string a,string b)
{
return a.size()<b.size();
}
int main()
{
freopen("pin.txt","r",stdin);
freopen("pou.txt","w",stdout);
int i,j,k;
while (cin >> s[n])
n++;
sort(s,s+n,cmp);
for (i=0;i<n;i++)
{
string tmp=s[i];
sort(tmp.begin(),tmp.end());
ins(tmp,i);
}
for (i=0;i<n;i++)
{
dp[i]=1;p[i]=-1;
int len=s[i].size();
string tt=s[i];
sort(tt.begin(),tt.end());
for (j=0;j<len;j++)
{
string tmp=tt;
tmp.erase(tmp.begin()+j);
int k=find(tmp);
if (k==-1) continue;
if (dp[k]+1>dp[i])
{
dp[i]=dp[k]+1;
p[i]=k;
}
}
}
ans=0;
for (i=0;i<n;i++)
if (dp[i]>ans)
{
ans=dp[i];
k=i;
}
print(k);
return 0;
}