题意:某人要从1走到L点,中间有L-1个点可以走,他每次最少走d步。有m个条件,在第ti步不能走到pi点。问有多少种走法。
思路:大佬博客
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e7+1234;
const int MOD = 998244353;
int F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘
void init(){
inv[1] = 1;
for(int i = 2; i < N; i ++){
inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
}
F[0] = Finv[0] = 1;
for(int i = 1; i < N; i ++){
F[i] = F[i-1] * 1ll * i % MOD;
Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
}
}
int comb(int n, int m){//comb(n, m)就是C(n, m) 从n中选择m个
if(m < 0 || m > n) return 0;
return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
}
ll f[N],sum[N];
struct node{
int t,p;
}a[3005];
int cmp(node x,node y)
{
return x.t<y.t;
}
ll dp[N];
int main(){
init();
f[0]=sum[0]=1;
int l,d,m;
cin>>l>>d>>m;
for(int i=1;i<=l;i++)
{
if(i<d)
{
f[i]=0;
}
else
f[i]=(sum[i-d-1]+f[i-d])%MOD;
sum[i]=(sum[i-1]+f[i])%MOD;
}
for(int i=0;i<m;i++)
cin>>a[i].t>>a[i].p;
sort(a,a+m,cmp);
ll ans=f[l];
for(int i=0;i<m;i++)
{
dp[i]=comb(a[i].p-1ll*a[i].t*d+a[i].t-1,a[i].t-1);
for(int j=0;j<i;j++)
{
dp[i]=(dp[i]-dp[j]*comb(a[i].p-a[j].p-1ll*d*(a[i].t-a[j].t)+a[i].t-a[j].t-1,a[i].t-a[j].t-1)+MOD)%MOD;
}
ans=(ans-dp[i]*f[l-a[i].p]%MOD+MOD)%MOD;
}
cout<<ans<<endl;
return 0;
}