Memory and his friend Lexa are competing to get higher score in one popular computer game. Memory starts with score a and Lexa starts with score b. In a single turn, both Memory and Lexa get some integer in the range [ - k;k] (i.e. one integer among - k, - k + 1, - k + 2, ..., - 2, - 1, 0, 1, 2, ..., k - 1, k) and add them to their current scores. The game has exactly t turns. Memory and Lexa, however, are not good at this game, so they both always get a random integer at their turn.
Memory wonders how many possible games exist such that he ends with a strictly higher score than Lexa. Two games are considered to be different if in at least one turn at least one player gets different score. There are (2k + 1)2t games in total. Since the answer can be very large, you should print it modulo 109 + 7. Please solve this problem for Memory.
InputThe first and only line of input contains the four integers a, b, k, and t (1 ≤ a, b ≤ 100, 1 ≤ k ≤ 1000, 1 ≤ t ≤ 100) — the amount Memory and Lexa start with, the number k, and the number of turns respectively.
OutputPrint the number of possible games satisfying the conditions modulo 1 000 000 007 (109 + 7) in one line.
Examples Input 1 2 2 1 Output 6 Input 1 1 1 2 Output 31 Input 2 12 3 1 Output 0 NoteIn the first sample test, Memory starts with 1 and Lexa starts with 2. If Lexa picks - 2, Memory can pick 0, 1, or 2 to win. If Lexa picks - 1, Memory can pick 1 or 2 to win. If Lexa picks 0, Memory can pick 2 to win. If Lexa picks 1 or 2, Memory cannot win. Thus, there are 3 + 2 + 1 = 6 possible games in which Memory wins.
题目大意:
A一开始的分数是a,B一开始的分数是b,问最终A比B分数高的方案数。
一共t轮游戏,每轮游戏每个人可以在【-k,k】之间选一个数和自己的分数进行累加。
思路:
设定dp【i】【j】表示玩了i轮,分数为j的方案数,那么明显有:dp【i】【j】=dp【i-1】【j+v】(-k<=v<=k)那么这种题就很无趣了,直接维护一个前缀和的套路展现无疑啊。
那么维护两个选手的方案数,对应结果:
output+=ans【j】*ans2【j-v】(v>=1);
显然直接枚举还是会TLE ,那么继续维护一个前缀和即可。
Ac代码:
#include<stdio.h> #include<string.h> using namespace std; #define mod 1000000007 #define ll __int64 ll dp[105][300500]; ll sum[105][300500]; ll ans[300500]; ll ans2[300500]; ll preans2[300500]; ll kuaisucheng(ll a,ll b) { ll ans=0; while(b) { if(b&1) { ans=(ans+a); if(ans>=mod)ans-=mod; } a=(a+a); if(a>=mod)a-=mod; b/=2; } return ans; } int main() { ll a,b,k,t; while(~scanf("%I64d%I64d%I64d%I64d",&a,&b,&k,&t)) { int mid=150000; memset(sum,0,sizeof(sum)); memset(dp,0,sizeof(dp)); dp[0][a+mid]=1; for(int j=4000;j<=260000;j++)sum[0][j]=sum[0][j-1]+dp[0][j],sum[0][j]%=mod; for(int i=1;i<=t;i++) { for(int j=4000;j<=260000;j++) { if(j+k<=260000) dp[i][j]=(sum[i-1][j+k]-sum[i-1][j-k-1]+mod)%mod; } for(int j=4000;j<=260000;j++)sum[i][j]=sum[i][j-1]+dp[i][j],sum[i][j]%=mod; } for(int j=4000;j<=260000;j++)ans[j]=dp[t][j]; memset(sum,0,sizeof(sum)); memset(dp,0,sizeof(dp)); dp[0][b+mid]=1; for(int j=4000;j<=260000;j++)sum[0][j]=sum[0][j-1]+dp[0][j],sum[0][j]%=mod; for(int i=1;i<=t;i++) { for(int j=4000;j<=260000;j++) { if(j+k<=260000) dp[i][j]=(sum[i-1][j+k]-sum[i-1][j-k-1]+mod)%mod; } for(int j=4000;j<=260000;j++)sum[i][j]=sum[i][j-1]+dp[i][j],sum[i][j]%=mod; } for(int j=4000;j<=260000;j++)ans2[j]=dp[t][j]; ll output=0; for(int j=4500;j<=255000;j++)preans2[j]=preans2[j-1]+ans2[j],preans2[j]%=mod; for(int j=4500;j<=255000;j++)output+=kuaisucheng(preans2[j-1],ans[j]),output%=mod; printf("%I64d\n",output); } }