思路:dp。
状态:dp[i][j]表示到第i轮得分为j的方案数。
状态转移:dp[i][j]=∑dp[i-1][j-l](-k≤l≤k),这是一段连续的和,可以用前缀和优化。
代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mp make_pair #define pi acos(-1.0) #define pii pair<int,int> #define mem(a,b) memset(a,b,sizeof(a)) const int INF=0x7f7f7f7f; const int MOD=1e9+7; const int N=2e5+110; int dp[110][N]; int sum[N]; int a[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); int a,b,k,t; cin>>a>>b>>k>>t; dp[0][0]=1; for(int i=1;i<=t;i++) { sum[0]=dp[i-1][0]; for(int j=1;j<N;j++)sum[j]=(sum[j-1]+dp[i-1][j])%MOD;//sum[j]表示上一轮得到分数小于等于j的方案数 for(int j=0;j<N;j++)dp[i][j]=(sum[j]-(j-2*k-1>=0?sum[j-2*k-1]:0)+MOD)%MOD; } sum[0]=dp[t][0]; for(int j=1;j<N;j++)sum[j]=(sum[j-1]+dp[t][j])%MOD; ll ans=0; for(int i=0;i<=2*k*t;i++) { ans=(ans+(ll)dp[t][i]*(i+a-b>=1?sum[i+a-b-1]:0)%MOD)%MOD;//dp[t][i]表示Memory的方案数,sum[i+a-b-1]表示他朋友的方案数 } cout<<ans<<endl; return 0; }