zoukankan      html  css  js  c++  java
  • 『妙不可言系列2』CF1336C Kaavi and Magic Spell

    (mathrm{Problem})

    Kaavi, the mysterious fortune teller, deeply believes that one's fate is inevitable and unavoidable. Of course, she makes her living by predicting others' future. While doing divination, Kaavi believes that magic spells can provide great power for her to see the future.

    Kaavi has a string $ T $ of length $ m $ and all the strings with the prefix $ T $ are magic spells. Kaavi also has a string $ S $ of length $ n $ and an empty string $ A $ .

    During the divination, Kaavi needs to perform a sequence of operations. There are two different operations:

    • Delete the first character of (S) and add it at the front of (A) .
    • Delete the first character of (S) and add it at the back of (A) .

    Kaavi can perform no more than (n) operations. To finish the divination, she wants to know the number of different operation sequences to make (A) a magic spell (i.e. with the prefix (T) ). As her assistant, can you help her? The answer might be huge, so Kaavi only needs to know the answer modulo (998\,244\,353) .

    Two operation sequences are considered different if they are different in length or there exists an (i) that their (i) -th operation is different.

    A substring is a contiguous sequence of characters within a string. A prefix of a string (S) is a substring of (S) that occurs at the beginning of (S) .

    给定一个字符串 (S) 和一个字符串 (T),每次可以删掉 (S) 的第一个字符,然后放到一个初始为空的字符串 (A) 的首部或尾部,求有多少种不同的方法使得最后 (T)(A) 的前缀。

    (mathrm{Solution})

    这道题的特性在于,A串的特性是两边拓展的。我们可以从A串这个与众不同的特点来思考问题。

    • 对于不断两边拓展的问题需要想到区间DP

    这一点是解题的关键。但是这道题要求这个串满足T是该串的前缀,那我们可以在状态上做手脚。

    • (f[l][r])表示用((r-l+1))个S字符前后拼接形成A串,A串的区间([mathrm L, ext R])内的任意一个字符符合条件的方案数。这里字符i符合条件当且仅当满足(i>|T|)或者(ile |T|且A_i=T_i).

    那样我们就可以考虑使用区间DP的方式去进去转移了。

    我们考虑方程的转移,对于一个(l)(r)和区间的长度( ext{len=r-l+1}.)

    • 对于s[len]=t[i]或者i>m的情况,说明当前新加入的字母足以匹配可以成为开头或开头可以选择任意字母,那么就有:(f[i][j]+=f[i+1][j])
    • 对于s[len]=t[j]或者j>m的情况,同理:(f[i][j]+=f[i][j-1])

    (mathrm{Code})

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 4000;
    const int P = 998244353;
    
    int n, m;
    int f[N][N];
    char S[N], T[N];
    
    int main(void)
    {
    	cin >> S+1 >> T+1;
    	n = strlen(S+1);
    	m = strlen(T+1);
    	for (int i=1;i<=n;++i)
    		f[i][i] = (i > m || S[1] == T[i])*2;
    	for (int len=2;len<=n;++len)
    		for (int i=1;i+len-1<=n;++i) {
    			int j = i + len - 1;
    			if (S[len] == T[i] || i > m) f[i][j] = (f[i][j] + f[i+1][j]) % P;
    			if (S[len] == T[j] || j > m) f[i][j] = (f[i][j] + f[i][j-1]) % P;
    		} 	
    	int res = 0;
    	for (int i=m;i<=n;++i)
    		res = (res + f[1][i]) % P;
    	cout << res << endl;
    	return 0;
    } 
    
  • 相关阅读:
    第三章:模板扩展
    第二章:表单和模板
    第一章:引言
    ZABBIX 调用PYTHON脚本监控 磁盘剩余空间(创建模版,创建监控项,创建触发器)
    访问虚拟机中的架设的Web服务器
    服务器上的 Git
    windows命令
    POPTEST联合创始人李爱然的“IT培训创业的随想"
    老李分享:大数据性能调优案例
    老李思考:看夏洛特烦恼有感
  • 原文地址:https://www.cnblogs.com/pigzhouyb/p/12755540.html
Copyright © 2011-2022 走看看