首页 > 其他分享 >Luogu P4591 [TJOI2018] 碱基序列

Luogu P4591 [TJOI2018] 碱基序列

时间:2023-01-08 20:35:31浏览次数:64  
标签:10 P4591 le 匹配 int Luogu 字符串 const TJOI2018

链接
难度:\(\texttt{省选/NOI-}\)


有 \(k\) 组,每一组有 \(a_i\) 个字符串 \(t_{k,a_i}\),询问分别在每一组选一个字符串拼成的字符串在文本串 \(s\) 出现的个数的所有情况的总和对 \(10^9+7\) 取余的值。

数据范围:\(1\le k\le100,1\le a_i\le 10,1\le |t_{i,j}|,1\le |s|\le 10^4\)。


考虑 DP,设 \(f_{i,j}\) 为到第 \(i\) 组匹配到第 \(j\) 位的方案数。

则 \(f_{i,j}\) 只有可能由 \(i-1\) 组,且拼上第 \(i\) 组的其中一个字符串依然能匹配上 \(s\) 对应的位置。
所以可得转移方程 \(f_{i,j}=\sum_{k=1}^{a_i} f_{i-1,j-|t_{i,k}|}(\operatorname{cmp}(tp_{i-1,j-|t_{i,k}|}+t_{i,k},j))\)(\(tp_{i,j}\) 为对于 \(f_{i,j}\) 所拼成的字符串,\(\operatorname{cmp}(t,i)\) 为字符串 \(t\) 是否能在 第 \(i\) 位匹配上 \(s\))。

匹配 \(s\) 可用 KMP 求解,若匹配成功则说明可以转移。

时间复杂度 \(O(|s|\times\sum a_i)\)。


# include <bits/stdc++.h>
using namespace std;
const int N = 10000;
char S [N + 10], T [N + 10];
int KMP [N + 10];
const int K = 100;
int DP [K + 10] [N + 10];
const int mod = 1000000007;
int main () {
	ios :: sync_with_stdio (false);
	cin .tie (0);
	cout .tie (0);
	int k;
	cin >> k >> (S + 1);
	int n = strlen (S + 1);
	for (int i = 0; i <= n - k; ++ i) {
		DP [0] [i] = 1;
	}
	for (int i = 2, j = 0; i <= n; ++ i) {
		while (j && (S [i] ^ S [j + 1])) {
			j = KMP [j];
		}
		j += ! (S [i] ^ S [j + 1]);
		KMP [i] = j;
	}
	for (int h = 1; h <= k; ++ h) {
		int a;
		cin >> a;
		while (a --) {
			cin >> (T + 1);
			int m = strlen (T + 1);
			for (int i = 1, j = 0; i <= n; ++ i) {
				while (j && (S [i] ^ T [j + 1])) {
					j = KMP [j];
				}
				j += ! (S [i] ^ T [j + 1]);
				if (! (j ^ m)) {
					j = KMP [j];
					DP [h] [i] += DP [h - 1] [i - m], DP [h] [i] %= mod;
				}// 匹配成功可以由上一组转移
			}
		}
	}
	int ans = 0;
	for (int i = k; i <= n; ++ i) {
		ans += DP [k] [i], ans %= mod;
	}
	cout << ans;
	return 0; 
}

标签:10,P4591,le,匹配,int,Luogu,字符串,const,TJOI2018
From: https://www.cnblogs.com/lhzQAQ/p/17035274.html

相关文章

  • LibreOJ L2576 「TJOI2018」str
    链接难度:\(\texttt{?}\)有\(k\)组,每一组有\(a_i\)个字符串\(t_{k,a_i}\),询问分别在每一组选一个字符串拼成的字符串在文本串\(s\)出现的个数的所有情况的总和对......
  • 题解: Luogu P8894 「UOI-R1」求和
    题目链接:link前言我的一个学长在一次比赛中出了这道题,然后,我就把这道题切了其实这道题还是比较简单的,然后我就介绍一下我的比赛时的思路和做法30分做法根据标签我......
  • Luogu P2082 区间覆盖(加强版)
    链接难度:普及/提高-有\(n\)个区间\([s_i,t_i]\),求被这\(n\)个区间覆盖的长度。数据范围:\(n\le10^5,1\les_i<t_i\le10^17\)。把每个区间都换成一组匹配的括......
  • luogu P2757 [国家集训队]等差子序列
    Link题解降智了。。。首先我们不需要关心\(Len\)是多少,只需要找到长度为\(3\)的等差子序列就行了。然后就枚举中点\(mid\),看看存不存在\(l<mid<r\)使得\(a_{mi......
  • 题解 : Luogu P2197 【模板】nim 游戏
    题目链接:link结论如果$a_1\oplusa_2\oplus...\oplusa_n\not=0$,则先手必胜证明操作到最后时,每堆石子数都是\(0\),\(0\oplus0\oplus...\oplus0=0......
  • Luogu P4178 Tree
    LuoguP4178Tree难度:省选/NOI-标签:点分治\(\mathtt{blog}\)\(n\)个点的树,边\((u_i,v_i)\)有边权\(w_i\),询问距离\(\lek\)的点对数量。数据范围:\(n\le4\times......
  • POJ 2114 Boatherds / Luogu P3806 【模板】点分治1
    POJ2114Boatherds/LuoguP3806【模板】点分治1难度:\(\mathtt{?}\)/省选/NOI-标签:点分治\(\mathtt{blog}\)\(n\)个点的树,边\((u_i,v_i)\)有边权\(w_i\),\(m\)......
  • Luogu P5676 [GZOI2017] 小z玩游戏
    P5676[GZOI2017]小z玩游戏难度:提高+/省选-标签:Tarjan建图\(\mathtt{blog}\)有\(n\)组数\((w_i,e_i)\),如果当前数值为\(w_i\)即可改变为\(e_i\),如果当前数值......
  • Luogu6620 组合数问题 - 第二类斯特林数 -
    题目链接:https://www.luogu.com.cn/problem/P6620题解:其实就一个式子证明可以利用这个式子找一下规律$$k\binom{n}{k}=n\binom{n-1}{k-1}$$回到原题,把多项式拆开之......
  • Luogu4043 支线剧情 - 费用流 -
    题目链接:https://www.luogu.com.cn/problem/P4043题意:求图一个的路径并,使得所有边都包含且所有路径的权值之和最小,而且路径都是从1开始的题解:每条边都必须经过,容量设一......