题目链接:http://codeforces.com/problemset/problem/712/D
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.
The 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.
Print the number of possible games satisfying the conditions modulo 1 000 000 007 (109 + 7) in one line.
1 2 2 1
6
1 1 1 2
31
2 12 3 1
0
In 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和B玩游戏,初始A有a积分分,B有b积分。一共t(t<=100)回合,每回合两个人随机获得[-k,k]分数(k<=1000),问t回合后,A的积分大于B积分的局面数目。
题解:dp[i][j]表示i回合获得j积分的方法数,则dp[i][j] = sigma{-k<=l<=k}d[i-1][j-l];可以用前缀和优化DP。
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <stack>
#include <string>
#include <string.h>
#include <bitset>
#include <map>
#include <set>
#include <assert.h>
#include <iostream>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define x0 x0___
#define y0 y0___
#define pb push_back
#define SZ(X) ((int)X.size())
#define mp make_pair
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define ALL(X) X.begin(),X.end()
#define RALL(X) X.rbegin(),X.rend()
#define rep(i,j,k) for(int i = j;i <= k;i ++)
#define per(i,j,k) for(int i = j;i >= k;i --)
#define mem(a,p) memset(a,p,sizeof(a))
const ll MOD = 1E9 + 7;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
ll qmod(ll a,ll b,ll c) {ll res=1;a%=c; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%c;a=a*a%c;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
template<typename T, typename S>
void upmax(T& a,S b){if(a<b) a=b;}
template<typename T, typename S>
void upmin(T& a,S b){if(a>b) a=b;}
template<typename T>
void W(T m) {cout << m <<endl;}
void gettle() {while(1);}
void getre() {int t=0;t/=t;}
const int T = 101, K = 1011;
const int TK = T * K * 2 + K;
ll dp[TK+7];
ll pre1[TK+7];
ll pre2[TK+7];
int a, b, k, t;
ll sum(int l, int r)
{
if(r < l) return 0;
upmax(l, 1);
return pre1[r] - pre1[l-1];
}
int main()
{
scanf("%d %d %d %d", &a, &b, &k, &t);
rep(i,1,2*k+1) dp[i] = 1;
rep(i,1,TK) pre1[i] = pre1[i - 1] + dp[i];
rep (i,2,t) {
rep (j,1,TK) {
dp[j] = sum(j - 2 * k, j);
while(dp[j] < 0) dp[j] += MOD;
pre2[j] = (pre2[j - 1] + dp[j]) % MOD;
}
rep (j,1,TK) pre1[j] = pre2[j];
mem(pre2,0);
}
ll res = 0;
rep (i,1,TK) {
int t = min(TK, i+a-b-1);
if(t < 0) continue;
ll p = sum(1,i) - sum(1,i-1);
res = res + (p * sum(1, t) % MOD);
res = (res % MOD + MOD) % MOD;
}
printf("%lld\n", res);
return 0;
}