题目链接:HDOJ 5791

看上去就肯定是一个DP的,为什么?

数据量啊,n和m都是1000,那么dp【i】【j】很好定:a串的前i个和b串的前j个的子串匹配值

那么dp【n】【m】为答案咯


接下来就稍微的吐槽一下题解:(水题)好吧

毕竟还是自己弱了,这个状态转移得考虑到容斥原理

dp【i】【j】肯定是与dp【i-1】【j-1】,dp【i】【j-1】和dp【i-1】【j】有关

当a【i】!=b【j】时,

那么匹配数值应该就是以前的,dp【i-1】【j】+dp【i】【j-1】

但是,这两个部分是有公共部分的,想想怎么来的,交集是dp【i-1】【j-1】

当a【i】==b【j】时,

除了不相等的部分,相等的部分也变长了一格,还需要加上dp【i-1】【j-1】+1

所以dp转移有了


还有一点细节:因为出现了减号,要+mod再%mod来把值变成正的,贴个代码:

const int maxn=1050;
int a[maxn],b[maxn],n,m;
__int64 dp[maxn][maxn];
__int64 mod;
int main(){
	mod=1e9+7;
	//freopen("input.txt","r",stdin);	
	while(scanf("%d%d",&n,&m)!=EOF){
		__int64 ans=0;
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		for(int i=1;i<=m;i++) scanf("%d",&b[i]);
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)
			for(int j=1;j<=m;j++){
				//dp[i-1][j]
				//dp[i][j-1]
				if (a[i]!=b[j])
					dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
				else
					dp[i][j]=dp[i-1][j]+1+dp[i][j-1];
				dp[i][j]=dp[i][j]%mod;
			}
		//for(int i=1;i<=n;i++)
		//	for(int j=1;j<=m;j++)
		//		printf("%d%c",dp[i][j],j==m?'\n':' ');
		printf("%I64d\n",(dp[n][m]+mod)%mod);
	}
	return 0;
}