最强密码 (百度之星复赛 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 }
Every day is meaningful, keeping learning!