title
Simplify the meaning of the questions:
Solitaire, for a string \ (i \) , if the string \ (j \) the number of occurrences of all the characters in the ratio \ (i \) and only a great location \ (1 \) , it will be able to connect.
Solitaire seeking maximum length and programs.
analysis
Algorithm 1: Violence \ (Dp \) .
Consider the length \ (Dp \) , because the length of each will be added 1.
State transition equation is:
\ [F_i = \ max \ {FJ \ +}. 1, len_i = len_j. 1 and legally + \]
output scheme, then, like the recording at the transfer point.
Time complexity will not ah, reference benoble_ of the: \ (O (* 26 is \ sum_ sum_ {{len}} * len-len. 1 sum_ {}) \) .
Therefore, the limit for the \ (O (* 26 is \ {n-FRAC. 4} ^ {2}) \) .
Of course not optimized (or else wrote).
Algorithm 2: \ (hash + DAG \) longest road
For each string, a certain increase his character, whether visible string exists, if there is even an edge.
This map must be a \ (DAG \) , so the longest road running just fine.
How to judge it exists or not? The \ (26 \) letters \ (cnt ~ hash \) just fine.
code
\(60pts\)
#include<bits/stdc++.h>
const int maxn=1e4+10,maxm=105;
namespace IO
{
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x)
{
if (!x) *fe++=48;
if (x<0) *fe++='-', x=-x;
T num=0, ch[20];
while (x) ch[++num]=x%10+48, x/=10;
while (num) *fe++=ch[num--];
*fe++='\n';
}
}
using IO::read;
using IO::write;
template<typename T>inline bool chkMin(T &a,const T &b) { return a>b ? (a=b, true) : false; }
template<typename T>inline bool chkMax(T &a,const T &b) { return a<b ? (a=b, true) : false; }
char s[maxn][maxm];
int L=1e9,R,pos,ans;
int pre[maxn],f[maxn];
inline void dfs(int x)
{
if (!x) return ;
dfs(pre[x]);
puts(s[x]+1);
}
struct Orz{int l,c[26];}a[maxn];
inline bool check(int x,int y)
{
int p=0;
for (int i=0; i<26; ++i)
{
if (a[x].c[i]==a[y].c[i]) continue;
if (a[x].c[i]<a[y].c[i]) return 0;
if (a[x].c[i]>a[y].c[i]+1) return 0;
p^=1;
}
return p;
}
std::vector<int>len[maxm];
int main()
{
int n=0;
while (~scanf("%s",s[++n]+1))
{
a[n].l=strlen(s[n]+1);
for (int i=1; i<=a[n].l; ++i) ++a[n].c[s[n][i]-'a'];
}
--n;
for (int i=1; i<=n; ++i) len[a[i].l].push_back(i),chkMin(L,a[i].l),chkMax(R,a[i].l);
for (int l=L; l<=R; ++l)
{
// for (int i:len[l]) f[i]=1;
for (int i=0; i<(int)len[l].size(); ++i) f[len[l][i]]=1;
if (!(int)len[l-1].size()) continue;
// for (int i:len[l])
// {
// for (int j:len[l-1])
// if (check(i,j)) if (chkMax(f[i],f[j]+1)) pre[i]=j;
// if (chkMax(ans,f[i])) pos=i;
// }
for (int i=0; i<(int)len[l].size(); ++i)
{
for (int j=0; j<(int)len[l-1].size(); ++j)
if (check(len[l][i],len[l-1][j])) if (chkMax(f[len[l][i]],f[len[l-1][j]]+1)) pre[len[l][i]]=len[l-1][j];
if (chkMax(ans,f[len[l][i]])) pos=len[l][i];
}
}
write(ans),IO::flush();
dfs(pos);
return 0;
}
\(100pts\)
#include<bits/stdc++.h>
const int maxn=1e4+10,maxm=105,M=1e7;
typedef int iarr[maxn];
namespace IO
{
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x)
{
if (!x) *fe++=48;
if (x<0) *fe++='-', x=-x;
T num=0, ch[20];
while (x) ch[++num]=x%10+48, x/=10;
while (num) *fe++=ch[num--];
*fe++='\n';
}
}
using IO::read;
using IO::write;
template<typename T>inline bool chkMin(T &a,const T &b) { return a>b ? (a=b, true) : false; }
template<typename T>inline bool chkMax(T &a,const T &b) { return a<b ? (a=b, true) : false; }
inline int get(int*s)
{
int tmp=0;
for (int i=0; i<26; ++i) tmp=(233ll*tmp%M+s[i])%M;
return tmp;
}
int ver[maxn],Next[maxn],head[maxn],len,In[maxn];
inline void add(int x,int y)
{
ver[++len]=y,Next[len]=head[x],head[x]=len,++In[y];
}
char s[maxn][maxm];
int Stack[maxn],hs[M],top,ans,pos;
iarr dist,pre;
struct Orz{int l,c[26];}a[maxn];
int main()
{
int n=0;
while (~scanf("%s",s[++n]+1));
--n;
for (int i=1; i<=n; ++i)
{
a[i].l=strlen(s[i]+1);
for (int j=1; j<=a[i].l; ++j) ++a[i].c[s[i][j]-'a'];
hs[get(a[i].c)]=i;
}
for (int i=1; i<=n; ++i)
for (int j=0; j<26; ++j)
{
++a[i].c[j];
int y=get(a[i].c);
if (hs[y]) add(i,hs[y]);
--a[i].c[j];
}
std::queue<int>q;
for (int i=1; i<=n; ++i)
if (!In[i]) q.push(i),dist[i]=1;
while (!q.empty())
{
int x=q.front();
q.pop();
for (int i=head[x]; i; i=Next[i])
{
int y=ver[i];
dist[y]=dist[x]+1;
pre[y]=x;
if (!--In[y]) q.push(y);
}
}
for (int i=1; i<=n; ++i)
if (chkMax(ans,dist[i])) pos=i;
write(ans),IO::flush();
while (pos) Stack[++top]=pos, pos=pre[pos];
for (int i=top; i>=1; --i) puts(s[Stack[i]]+1);
return 0;
}