CodeForces 712 D.Memory and Scores(dp)

Description

Memory and his friend Lexa play the game, starting with a and B scores, each round of the game, two people scored a random number in [k,k], asked the number of programs that Memory scored higher than Lexa scores after the t round.

Input

Four integers a,b,k,t(1 < a,b < 100, 1 < K < 1000, 1 < T < 100)

Output

Number of output schemes, result module 109 + 7

Sample Input

1 2 2 1

Sample Output

6

Solution

Using dp[i][j] to denote the number of schemes whose difference of the first round is j, enumerating that the difference of the second round is shifted

dp[i][j]==∑l=02k(2k+1−l)⋅dp[i−1][j−l]+∑l=−2k−1(2k+1+l)⋅dp[i−1][j−l]dp[i][j−1]−∑l=12k+1dp[i−1][j−l]+∑−2k0dp[i−1][j−l]

So as long as the prefix of dp[i_1] is maintained and O(1) can be transferred at a time, and the time complexity O(t2k) is maintained, the answer is I > b adp[t][i]

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=420000;
#define mod 1000000007
int a,b,k,t,dp[2][maxn],sum[maxn];
int n=400000,m=200000;
void add(int &x,int y)
{
    x=x+y>=mod?x+y-mod:x+y;
}
int Solve(int l,int r)
{
    l=max(1,l),r=min(r,n);
    return (sum[r]-sum[l-1]+mod)%mod;
}
int main()
{
    scanf("%d%d%d%d",&a,&b,&k,&t);
    int cur=0;
    dp[cur][m]=1;
    for(int i=1;i<=t;i++)
    {
        cur^=1;
        memset(dp[cur],0,sizeof(dp[cur]));
        sum[0]=dp[cur^1][0];
        for(int j=1;j<=n;j++)sum[j]=(sum[j-1]+dp[cur^1][j])%mod;
        for(int j=0;j<=n;j++)
        {
            if(j==0)
            {
                for(int l=0;l<=2*k;l++)
                    add(dp[cur][j],(ll)(2*k+1-l)*dp[cur^1][j+l]%mod);
            }
            else
            {
                dp[cur][j]=dp[cur][j-1];
                add(dp[cur][j],mod-Solve(j-2*k-1,j-1));
                add(dp[cur][j],Solve(j,j+2*k));
            }
        }
    }
    int ans=0;
    for(int i=m+1+b-a;i<=n;i++)add(ans,dp[cur][i]);
    printf("%d\n",ans);
    return 0;
}

Posted by sublevel4 on Wed, 06 Feb 2019 13:24:16 -0800