算法二十七:子序列
其他
2018-07-05 04:49:29
阅读次数: 0
描述
给定一个字符串,求出该字符串有多少不同的子序列。
子序列:字符串中按顺序抽出一些字符得到的串。比如字符串abcd里,ab、ac、ad、abc、acd都是子序列。
输出
输出不同的子序列的个数除以23333得到的余数。
样例解释
有这些子序列:
a,b,c,aa,ab,ac,ba,bb,bc,aba,abb,abc,aab,aac,bab,bac,bbc,abab,abac,abbc,aabc,babc,ababc
提示
[令f(i)f(i)为前ii中本质不同的的子序列个数,令pre(i)pre(i)表示字符sisi之前出现的位置,则]
[f(i)={f(i−1)+f(i−1)+1pre(i)=0f(i−1)+f(i−1)−f(pre(i)−1)pre(i)≠0f(i)={f(i−1)+f(i−1)+1pre(i)=0f(i−1)+f(i−1)−f(pre(i)−1)pre(i)≠0]
[答案等于f(n)f(n).]
一. 伪代码
二. 具体实现(C++)
#include <bits/stdc++.h>
using namespace std;
// ================= 代码实现开始 =================
const int N = 500005, mo = 23333;
int f[N], p[N], last[26];
// 为了减少复制开销,我们直接读入信息到全局变量中
// s:题目所给字符串
char s[N];
// 求出字符串s有多少不同的子序列
// 返回值:s不同子序列的数量,返回值对mo取模
int getAnswer() {
int n = strlen(s + 1);
for(int i = 1; i<=n; ++i){
int a = s[i] - 'a';
p[i] = last[a];
last[a] = i;
}
f[0] = 0;
for(int i = 1; i <= n; ++i){
f[i] = (p[i] == 0)?
(f[i - 1] + f[i - 1] +1):(f[i - 1]+f[i - 1]-f[p[i]-1]);
f[i]%=mo;
}
return (f[n] + mo) % mo;
}
// ================= 代码实现结束 =================
转载自blog.csdn.net/wydyd110/article/details/80909371