Codeforces 712D

712D - Memory and Scores

思路: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;
} 
原文地址:https://www.cnblogs.com/widsom/p/7417092.html