zoukankan      html  css  js  c++  java
  • [TJOI2018]碱基序列

    [TJOI2018 碱基序列](https://www.luogu.com.cn/problem/P4591)
    
    偷懒直接 SAM 上 DP。
    
    设 dp(i,j) 表示用前 i 行氨基酸匹配到状态 j 的方案数。
    
    由于这个题面比较玄学, 复杂度就挺玄学, 随手加点剪枝就可以很快。
    
    ```cpp
    #include <bits/stdc++.h>
    typedef long long LL;
    using namespace std;
    
    const int mo = 1e9 + 7;
    
    int siz[20113];
    struct node {
    	int f, len, t[26];
    } t[20113];
    int a[20113];
    
    int tot = 1, las = 1;
    void extnd (int c) {
    	int np = ++ tot, p = las; las = np;
    	t[np].len = t[p].len + 1;
    	for (; p && !t[p].t[c]; p = t[p].f) t[p].t[c] = np;
    	if (!p) t[np].f = 1;
    	else {
    		int v = t[p].t[c];
    		if (t[v].len == t[p].len + 1) t[np].f = v;
    		else {
    			int nv = ++ tot; t[nv] = t[v];
    			t[nv].len = t[p].len + 1;
    			for (; p && t[p].t[c] == v; p = t[p].f) t[p].t[c] = nv;
    			t[np].f = t[v].f = nv;
    		}
    	}
    	siz[np] += 1;
    }
    
    int n;
    char s[10003];
    
    LL dp[103][20113];
    bool cmp (int s1, int s2) { return t[s1].len < t[s2].len; }
    
    int main()
    {
    	scanf ("%d%s", & n, s);
    	int len = strlen (s);
    	for (int i = 0; i < len; ++ i) extnd (s[i] - 'A');
    	dp[0][1] = 1ll;
    	for (int id = 1; id <= n; ++ id)
    	{
    		int k;
    		scanf ("%d", &k);
    		for (int i = 0; i < k; ++ i) {
    			scanf ("%s", s); int sl = strlen (s); if (sl > len) continue;
    			for (int sta = 1; sta <= tot; ++ sta) if(dp[id - 1][sta]) {
    				int now = sta;
    				// tran
    				for (int j = 0; j < sl; ++ j) { now = t[now].t[s[j] - 'A']; if (!now) break; }
    				if (now) dp[id][now] += dp[id - 1][sta], dp[id][now] %= mo;
    			}
    		}
    	}
    	for (int i = 1; i <= tot; ++ i) a[i] = i;
    	sort (a + 1, a + 1 + tot, cmp);
    	for (int i = tot; i >= 1; -- i) if (t[a[i]].f) siz[t[a[i]].f] += siz[a[i]];
    	LL ans = 0ll;
    	for (int i = 1; i <= tot; ++ i) ans += (LL)dp[n][i] * siz[i] % mo, ans = ans % mo;
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    bcdedit /copy {current} /d "xxx" 报错,提示找不到系统文件
    Moving docker images location to different partition
    docker 使用save和load命令来转移image
    docker image rm ubuntu 失败
    yum国内镜像配置
    VMware下安装CentOS7 无法通过桥接模式进行联网
    docker大概理解
    windows cmd 切换磁盘
    使用Git向GitHub上上传代码
    抛砖引玉——进程和线程的理解方式
  • 原文地址:https://www.cnblogs.com/tztqwq/p/14472974.html
Copyright © 2011-2022 走看看