目录
1007 Matryoshka Doll(DP)
分析:有n个套娃,大小为a1<=a2<=……<=an,要将这些套娃分成k组,每组套娃按照大小排序后相邻两个套娃之间的大小差距要求>=r,求方案数。
设f[i][j]表示将前i个娃分成j组的合法方案数
f[i][j]=(f[i-1][j-1]+1ll*f[i-1][j]*max(0,j-t))%mod
f[i-1][j-1]是前i-1个套娃分成了j-1组,第i个套娃单独成为一组的情况;
1ll*f[i-1][j]*max(0,j-t)是前i-1个套娃分成了j组,第i个套娃放在已经分好的j组的其中一组里面,需要找到有多少组是可以放下第i个套娃的
/**/
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
int T;
int a[5005],f[5005][5005];//f[i][j]表示将前i个娃分成j组的合法方案数
int main(){
cin>>T;
while(T--){
int k,n;
int r;
cin>>n>>k>>r;
f[0][0]=1;//注意初始化
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
int t=i-1;//记录有多少个满足a[i]-a[j]>=r
while(t&&a[i]-a[t]<r) t--;//a[i]-a[t]<r不满足题意
t=i-t-1; //a[i]可以加入的组数
for(int j=1;j<=i;j++){
f[i][j]=(f[i-1][j-1]+1ll*f[i-1][j]*max(0,j-t))%mod;
}
}
cout<<f[n][k]<<endl;
}
}