子串sol

Posted hangzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了子串sol相关的知识,希望对你有一定的参考价值。

子串
字符串上的dp
(f(i,j,k))表示将A前i个字符划分成k段匹配了B中前j个字符的种数
考虑(f(i,j,k))的转移,不仅有(f(i-1,j,k))
(A(i)=B(j))时可以由(f(i-1,j-1,k-1))转移过来
(A(i)=B(j)并且A(i-1)=B(j-1))时,可以由(f(i-2,j-2,k-1))转移过来
如果对每一位都找到前面所有可以匹配,较为慢,更高效的方式是用(sum(i,j,k))表示当前可以转移过来的状态和,若(A(i)=B(j))(sum(i,j,k)=sum(i-1,j-1,k)+f(i-1,j-1,k-1))

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define SZ(x) ((int)x.size())
#define ALL(x) x.begin(),x.end()
#define U(i,u) for(register int i=head[u];i;i=nxt[i])
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
#define per(i,a,b) for(register int i=(a);i>=(b);--i)
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> PII;
typedef vector<int> VI;
template<class T> inline void read(T &x){
	x=0;char c=getchar();int f=1;
	while(!isdigit(c)){if(c==‘-‘)f=-1;c=getchar();}
	while(isdigit(c)){x=x*10+c-‘0‘;c=getchar();}x*=f;
}
template<class T> inline void cmin(T &x, T y){x=x<y?x:y;}
template<class T> inline void cmax(T &x, T y){x=x>y?x:y;}
const int N=1001;
const int M=201;
const int P=1000000007;
int n,m,k;
char a[N],b[N];
ll f[M][M],sum[M][M];
int main(){
	read(n);read(m);read(k);scanf("%s",a+1);scanf("%s",b+1);
	f[0][0]=1;rep(i,1,n)per(j,m,1)per(t,k,1){
		f[j][t]=(f[j][t]+(sum[j][t]=(a[i]==b[j])?sum[j-1][t]+f[j-1][t-1]:0))%P;
	}printf("%lld
",f[m][k]);
	return 0;
}






以上是关于子串sol的主要内容,如果未能解决你的问题,请参考以下文章

CF1037G A Game on Strings Sol

CF17E Palisection

HDU4622: Reincarnation

[HihoCoder1413]Rikka with String

Solr Highlighting:如何为同一字段请求多个片段长度?

bzoj3277: 串