2021牛客暑期多校训练营5 D.Double Strings(容斥dp)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021牛客暑期多校训练营5 D.Double Strings(容斥dp)相关的知识,希望对你有一定的参考价值。

LINK

考虑合法的序列,必定有一个分割点 k k k使得 a k < b k a_k<b_k ak<bk

且在此之前相当于可以有一段串 A A A和串 B B B的公共子序列接在前面

在此之后怎么选都无所谓,只需要满足选出来的长度相等即可

我们定义 f [ i ] [ j ] f[i][j] f[i][j]表示 A [ 1 , i ] A[1,i] A[1,i] B [ 1 , j ] B[1,j] B[1,j]有多少种公共子序列

a i ! = b j a_i!=b_j ai!=bj时,考虑容斥一下

f [ i ] [ j ] = f [ i ] [ j − 1 ] + f [ i − 1 ] [ j ] − f [ i − 1 ] [ j − 1 ] f[i][j]=f[i][j-1]+f[i-1][j]-f[i-1][j-1] f[i][j]=f[i][j1]+f[i1][j]f[i1][j1]

a i = = b j a_i==b_j ai==bj,此时还可以用这两个字母加在 f [ i − 1 ] [ j − 1 ] f[i-1][j-1] f[i1][j1]的后面,所以方案多了 f [ i − 1 ] [ j − 1 ] + 1 f[i-1][j-1]+1 f[i1][j1]+1

f [ i ] [ j ] = f [ i ] [ j − 1 ] + f [ i − 1 ] [ j ] + 1 f[i][j]=f[i][j-1]+f[i-1][j]+1 f[i][j]=f[i][j1]+f[i1][j]+1

定义 z [ i ] [ j ] z[i][j] z[i][j]表示 A A A串后缀长为 i i i B B B串后缀长为 j j j,从中取出子序列满足长度相等的情况

直接抽象成后缀所有字母都相等,求一个公共子序列即可,转移为

z [ i ] [ j ] = z [ i ] [ j − 1 ] + z [ i − 1 ] [ j ] + 1 z[i][j]=z[i][j-1]+z[i-1][j]+1 z[i][j]=z[i][j1]+z[i1][j]+1

于是我们直接枚举 a i < b j a_i<b_j ai<bj计算答案,以这个为分割线的方案有

( f [ i − 1 ] [ j − 1 ] + 1 ) ∗ ( z [ n − i ] [ m − j ] + 1 ) (f[i-1][j-1]+1)*(z[n-i][m-j]+1) (f[i1][j1]+1)(z[ni][mj]+1)

其中加 1 1 1是因为前后都可以为空,时间复杂度 O ( n 2 ) O(n^2) O(n2)

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5009;
const int mod = 1e9+7;
char a[maxn],b[maxn];
int n,m,f[maxn][maxn],z[maxn][maxn];
signed main()
{
	cin >> ( a+1 ) >> ( b+1 );
	n = strlen( a+1 ); m = strlen( b+1 );
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		z[i][j] = ( 1ll*z[i-1][j]+z[i][j-1]+1 )%mod;
		if( a[i]==b[j] )
			f[i][j] = ( 1ll*f[i][j-1]+f[i-1][j]+1 )%mod;
		else
			f[i][j] = ( 1ll*f[i][j-1]+f[i-1][j]-f[i-1][j-1] )%mod;
	}
	long long ans = 0;
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		if( a[i]<b[j] )
			ans = ( 1ll*ans+( 1+1ll*f[i-1][j-1] )*( 1+z[n-i][m-j] )%mod )%mod;
	}
	cout << ( ans%mod+mod )%mod;
}

以上是关于2021牛客暑期多校训练营5 D.Double Strings(容斥dp)的主要内容,如果未能解决你的问题,请参考以下文章

2021牛客暑期多校训练营5 C. Cheating and Stealing(模拟,思维)

2021牛客暑期多校训练营3

2021牛客暑期多校训练营1

2021牛客暑期多校训练营5,签到题BDHJK

2021牛客暑期多校训练营1 Hash Function(同余/NTT)

2021牛客暑期多校训练营1 Alice and Bob(结论,sg打表|优化)