题目大意
将两个排列随意归并,求能得到多少本质不同的序列。
DP
直接转移会算重。
手玩+感受一下发现容斥系数是卡特兰数。
详见代码。
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=2000+10,mo=1000000007;
int dp[maxn][maxn],f[maxn],a[maxn],b[maxn];
int i,j,k,l,t,n,m,ans;
int main(){
freopen("merge.in","r",stdin);freopen("merge.out","w",stdout);
scanf("%d",&n);
fo(i,1,n) scanf("%d",&a[i]);
fo(i,1,n) scanf("%d",&b[i]);
f[0]=f[1]=1;
fo(i,2,n)
fo(j,0,i-1)
(f[i]+=(ll)f[i-j-1]*f[j]%mo)%=mo;
fo(i,0,n) dp[i][0]=dp[0][i]=1;
fo(i,1,n)
fo(j,1,n){
dp[i][j]=(dp[i-1][j]+dp[i][j-1])%mo;
if (a[i]==b[j]){
k=0;
while (i-k>0&&j-k>0&&a[i-k]==b[j-k]){
k++;
(dp[i][j]-=(ll)dp[i-k][j-k]*f[k-1]%mo)%=mo;
}
}
}
ans=dp[n][n];
(ans+=mo)%=mo;
printf("%d\n",ans);
}