最强密码 (百度之星复赛 T5)

题目大意:

给出一个字符串A,要求最短的字符串B,B不是A的子序列。 求最短长度 和 最短的字符串个数    |A|<=105.

题解:

1.比赛的时候没有想出来,时隔一个多月又看到了这道题,虽然已经退役,还是下决心把它弄懂。

2.网络上基本都是直接贴代码的.我还是简要的写一写解法:

可以想象我们在字符串A上移动。一开始在一个起始节点(0号节点)上,如果我们选了字符p,现在在k号节点上,那么我们可以直接跳到p下一次出现的位置r(如果没有,跳到n+1号点)。

因为k,r直接没有字符p,就无需考虑它们之间的点.

所以F[i]表示移动到点i的最小步数,G[i]表示相应的方案数。 预处理出nxt[i][j]表示A[i+1 ... n]最左边出现字符j的位置。也就是节点之间的边。

从i可以通过选取字符j直接走到nxt[i][j]. 转移见代码。

 1         for (int i=1;i<=n+1;i++) f[i]=Inf,g[i]=0;
 2         for (int i=0;i<=n;i++)
 3         {
 4             if (f[i]==Inf) continue;
 5             for (int j=0;j<26;j++)
 6             {
 7                 if (f[i]+1<f[nxt[i][j]]) f[nxt[i][j]]=f[i]+1,g[nxt[i][j]]=0;
 8                 if (f[nxt[i][j]]==f[i]+1) g[nxt[i][j]]=Add(g[nxt[i][j]],g[i]);
 9             }
10         }
原文地址:https://www.cnblogs.com/vb4896/p/4662905.html