ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷P2679 子串

2022-05-04 02:31:38  阅读:132  来源: 互联网

标签:子串 字符 洛谷 P2679 std sb 匹配 sa dp


题目链接

  算是一个计数类的\(dp\),首先我们先确定状态数有多少个,一个是字符串\(a\)现在匹配到了第几位,一个是字符串\(b\)现在匹配到了第几位,另一个就是我们现在分成了多少组从字符串\(a\)中挑选出一段子串。这三个状态是最直接的状态,还有另一个就是我们是否要选择当前的字符\(a[i]\)来进行匹配,这个只有两种可能也就是选或不选两种,我们分别用\(0\)和\(1\)来表示选或不选的决策。
对于我们状态转移的过程中只会出现两种可能也就是\(a[i] == b[j]\)或者\(a[i] \neq b[j]\)这两种可能。

如果是\(a[i] == b[j]\)这种情况。

  我们可以选择选当前的位置上的\(a[i]\)去匹配,也可以不选择,这就又是两种决策了,所以这个状态我们在转移的时候选或不选两种都是要更新的。
如果是选就是

dp[i][j][p][1] = dp[i - 1][j - 1][p][1] + dp[i - 1][j - 1][p - 1][1] + dp[i - 1][j - 1][p - 1][0];

其中dp[i][j][p][1]表示的是在我们选择用当前的\(a[i]\)去和\(b[j]\)匹配并且将\(a[i]\)放在当前的子串中,dp[i - 1][j - 1][p][1]表示的是使用匹配前一次的状态并且使用当上一个字符的方案数,dp[i - 1][j - 1][p - 1][1]表示的是将当前匹配上的字符纳入上一次的子串中,并且使用上一次的字符的方案数,dp[i - 1][j - 1][p - 1][0]表示的就是使用匹配前一次的状态并且不使用上一次匹配的字符的方案数。
如果不选择当前的字符,那就是

dp[i][j][p][0] = dp[i - 1][j][p][0] + dp[i - 1][j][p][1];

表示的就是没有使用字符,并且\(b\)串匹配的长度还是\(j\)的方案数。

如果是\(a[i] \neq b[j]\)这种情况的话

  我们只能选择不匹配的情况,转移方程同上。还有就是因为匹配不上所以这一次如果是选的这个字符的话,那么方案数一定是0,所以还有一个赋值的过程

dp[i][j][p][0] = dp[i - 1][j][p][0] + dp[i - 1][j][p][1];
dp[i][j][p][1] = 0;

完成上面的操作这个题就完成了

int main() {
	std::cin.tie(nullptr)->sync_with_stdio(false);

	int n, m, k;
	std::cin >> n >> m >> k;

	std::string sa, sb;
	std::cin >> sa >> sb;
	sa = " " + sa;
	sb = " " + sb;

	dp[1][0][0][0] = 1;
	dp[0][0][0][0] = 1;

	for (int i = 1; i <= n; i ++ ) {
		for (int j = 1; j <= m; j ++ ) {
			for (int p = 1; p <= k; p ++ ) {
				if (sa[i] == sb[j]) {
					dp[i % 2][j][p][1] = dp[(i - 1) % 2][j - 1][p][1] + dp[(i - 1) % 2][j - 1][p - 1][1] + dp[(i - 1) % 2][j - 1][p - 1][0];
					dp[i % 2][j][p][0] = dp[(i - 1) % 2][j][p][0] + dp[(i - 1) % 2][j][p][1];
				} else {
					dp[i % 2][j][p][0] = dp[(i - 1) % 2][j][p][0] + dp[(i - 1) % 2][j][p][1];
					dp[i % 2][j][p][1] = 0;
				}
			}
		}
	}

	Z ans = dp[n % 2][m][k][1] +dp[n % 2][m][k][0];
	std::cout << ans.val() << "\n";

	return 0;
}

标签:子串,字符,洛谷,P2679,std,sb,匹配,sa,dp
来源: https://www.cnblogs.com/Haven-/p/16220202.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有