luogu2679 子串
题目大意
有两个仅包含小写英文字母的字符串 A 和 B。现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出 的位置不同也认为是不同的方案。对于所有 10 组数据:1≤n≤1000,1≤m≤200,1≤k≤m。
题解
本题的错误解法是定义状态$f(i, j, k)$为字符串$A$的前$i$个字符,字符串$B$的前$j$个字符已经匹配完,且已经分了$k$块时的方案最多为多少,状态转移为$f(i+1,j,k)+=f(i,j,k),若A_{i+1}=B_{j+1},则f(i+1,j+1,k)+=f(i,j,k),f(i+1,j+1,k+1)+=f(i,j,k)$。
本算法错在我们没有记录$f(i,j,k)$中$i$有没有选在子串中,这使各类关于$k$的转移,如$f(i+1,j+1,k)+=f(i,j,k)$等,不成立。
所以正确解法为定义状态$f(i,j,k,0)$表示第$i$位选在子串中,$f(i,j,k,1)$表示没有选,这样就有递归式:$f(i+1,j,k,0)+=f(i,j,k,0),若A_{i+1}=B_{i+1},f(i+1,j+1,k+1,1)+=f(i,j,k,0)$;$f(i+1,j,k,0)+=f(i,j,k,1),若A_{i+1}=B_{i+1},f(i+1,j+1,k,1)+=f(i,j,k,1),f(i+1,j+1,k+1,1)+=f(i,j,k,1)$。初始条件$f(i,0,0,0)=1$
踩过的坑
- 滚动数组每一次都要清空!
- $j=0$时,只有$f(i,0,0,0)$有意义,其它都没有意义,所以$f(i,0,...)$不能向$f(i+1,0,...)$转移。
- 最后输出结果的时候别忘了取模呀!
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; #define ll long long
#define F(i, j, k, t) DP[(i) & 1][j][k][t]
const int MAX_N = 1010, MAX_M = 210;
const ll P = 1e9 + 7;
char A[MAX_N], B[MAX_M];
ll DP[2][MAX_M][MAX_M][2];
int N, M, K; ll Dp()
{
A[0] = '*', B[0] = '-';
for (int i = 0; i <= N; i++)
{
memset(DP[i + 1 & 1], 0, sizeof(DP[i + 1 & 1]));
F(i, 0, 0, 0) = 1;
for (int j = 0; j <= M; j++)
for (int k = 0; k <= K; k++)
{
//t = 1
if (j > 0)
F(i + 1, j, k, 0) = (F(i + 1, j, k, 0) + F(i, j, k, 1)) % P;
if (A[i + 1] == B[j + 1])
{
F(i + 1, j + 1, k, 1) = (F(i + 1, j + 1, k, 1) + F(i, j, k, 1)) % P;
F(i + 1, j + 1, k + 1, 1) = (F(i + 1, j + 1, k + 1, 1) + F(i, j, k, 1)) % P;
}
//t = 0
if (j > 0)
F(i + 1, j, k, 0) = (F(i + 1, j, k, 0) + F(i, j, k, 0)) % P;
if (A[i + 1] == B[j + 1])
F(i + 1, j + 1, k + 1, 1) = (F(i + 1, j + 1, k + 1, 1) + F(i, j, k, 0)) % P;
}
}
return (F(N, M, K, 0) + F(N, M, K, 1)) % P;
} int main()
{
scanf("%d%d%d\n", &N, &M, &K);
scanf("%s", A + 1);
scanf("%s", B + 1);
printf("%lld\n", Dp());
return 0;
}
luogu2679 子串的更多相关文章
- [luogu2679] 子串 (多维dp)
传送门 Description 有两个仅包含小写英文字母的字符串 A 和 B . 现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来 ...
- luogu2679 [NOIp2015]子串 (dp)
设f[i][j][k][b]表示在A串第i位.这是第j组.B串第k位.i号选不选(b=0/1) 那么就有$f[i][j][k][1]=(A[i]==B[k])*(f[i-1][j-1][k][0]+f ...
- LeetCode[5] 最长的回文子串
题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...
- 最长回文子串-LeetCode 5 Longest Palindromic Substring
题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...
- C语言计算字符串子串出现的次数
#include<stdio.h>#include<string.h>int substring(char *str,char *str1);//函数原型int main(vo ...
- [LeetCode] Longest Substring with At Most Two Distinct Characters 最多有两个不同字符的最长子串
Given a string S, find the length of the longest substring T that contains at most two distinct char ...
- [LeetCode] Minimum Window Substring 最小窗口子串
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
- [LeetCode] Substring with Concatenation of All Words 串联所有单词的子串
You are given a string, s, and a list of words, words, that are all of the same length. Find all sta ...
- [LeetCode] Longest Substring Without Repeating Characters 最长无重复子串
Given a string, find the length of the longest substring without repeating characters. For example, ...
随机推荐
- Codeforces_766_D_(并查集)
D. Mahmoud and a Dictionary time limit per test 4 seconds memory limit per test 256 megabytes input ...
- R语言学习 - 热图美化
实际应用中,异常值的出现会毁掉一张热图.这通常不是我们想要的.为了更好的可视化效果,需要对数据做些预处理,主要有对数转换,Z-score转换,抹去异常值,非线性颜色等方式. 对数转换 为了方便描述,假 ...
- vue基础---列表渲染
首先简单回顾下v-for‘指令 <ol id="list_area"> <li v-for="book in books">{{book ...
- 安迪的第一个字典(Andy's First Dictionary,Uva 10815)
输入一个文本,找出所有不同的单词(连续的字母序列),按字典序从小到大输出.单 词不区分大小写. 样例输入: Adventures in Disneyland Two blondes were goin ...
- 入门系列(一) 微信小程序简介
一.简介 1.目录结构 首先,我们使用微信公众平台提供的开发者工具,创建一个简单的小程序项目,观察项目的目录结构 不难看出,一个典型的微信小程序,通常包含一个描述整体的主体部分,以及一个描述页面的 p ...
- python学习,使用requests库来模拟登录github,post请求。
这次我们要模拟登录的页面是 https://github.com/login 首先我们先尝试着登陆一遍分析一下请求, 打开开发者工具下的network选项, 可以很清楚的看到这个会话session,而 ...
- JMeter测试websocket
今天公司要测websocket,搞了一天踩了不少坑,关键是还没爬出来,BOSS让回家再理理思路,没办法到家就开干. 一.家里玩的还是2.1的,为了少踩坑,先下个JMeter5.1.1(他们说4版本也行 ...
- wannafly-day1 Problem A - Birthday
思路:队友贪心WA了,然后就没有然后了,自己也是第一次接触最小费用流的题.借这个题来学习一下,利用Spfa每次来找到一个最短的路径同时保存路径,每一次寻找最短路径就将这条路的最小费用流给剪掉,然后继续 ...
- Trie树 hihocoder 1014
Trie树 hihocoder 1014 传送门 字典树的基本应用 #include<queue> #include<cmath> #include<cstdio> ...
- HDU 1212 大整数的取模运算
因为这里是MOD最大为100000 所以我将字符串看作5个一组,并记录后面跟了多少个100000 每次取5个数根据其数据进行取模更新 注意过程中 100000*100000会超int #include ...