令
fi,j,k
表示约翰在前
i
中选
就可以列出方程:
其中 fi−1,j,k+fi,j−1,k−fi−1,j−1,k 表示的是之前的答案。
因为 fi−1,j,k+fi,j−1,k 重复计算了 fi−1,j−1,k 的答案,所以要减去 fi−1,j−1,k 。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 1010
#define M 1000000009
int a[N],b[N],p,i,j,k,n,m,f[N][N][11];
inline int Max(int x,int y){return x<y?y:x;}
int main(){
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
for(j=1;j<=m;j++)scanf("%d",&b[j]);
for(i=0;i<=n;i++)for(j=0;j<=m;j++)f[i][j][0]=1;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
for(p=1;p<=k&&p<=i&&p<=j;p++){
f[i][j][p]=((f[i-1][j][p]+f[i][j-1][p])%M-f[i-1][j-1][p])%M;
if(a[i]>b[j])f[i][j][p]=(f[i][j][p]+f[i-1][j-1][p-1])%M;
}
printf("%d\n",(f[n][m][k]+M)%M);
return 0;
}