题意:就是a,b玩游戏,a的起始分数为a,b的起始分数为b,每一轮两个都随机加 [-k k]的一个数 问你a比b的结果有几种
思路:因为两个人不互相干扰 看了一下数据范围 直接记下了每一轮的状态 即dp[i][j]表示第i轮有j分数有多少 最后比较一下
ps:虽然很容易想 但是太暴力了 一点都不优雅 后来发现有很简单的快的方法
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
#define LL long long
#define MAX 300000
#define MID 150000
#define MOD 1000000007
LL dp1[105][MAX];
LL dp2[105][MAX];
LL l[MAX];
LL r[MAX];
int main()
{
int a,b,k,t;
scanf("%d%d%d%d",&a,&b,&k,&t);
dp1[0][MID+a]=1;
for(int i=1;i<=t;i++)
{
int up=a+k*i+MID;
int down=a-k*i+MID;
for(int j=down;j<=up;j++)
{
l[j]=(dp1[i-1][j]+l[j-1]-dp1[i-1][j-k-1])%MOD;
}
for(int j=up;j>=down;j--)
{
r[j]=(dp1[i-1][j]+r[j+1]-dp1[i-1][j+k+1])%MOD;
}
for(int j=down;j<=up;j++)
{
dp1[i][j]=(l[j]+r[j]-dp1[i-1][j])%MOD;
}
}
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
dp2[0][MID+b]=1;
for(int i=1;i<=t;i++)
{
int up=b+k*i+MID;
int down=b-k*i+MID;
for(int j=down;j<=up;j++)
{
l[j]=(dp2[i-1][j]+l[j-1]-dp2[i-1][j-k-1])%MOD;
}
for(int j=up;j>=down;j--)
{
r[j]=(dp2[i-1][j]+r[j+1]-dp2[i-1][j+k+1])%MOD;
}
for(int j=down;j<=up;j++)
{
dp2[i][j]=(l[j]+r[j]-dp2[i-1][j])%MOD;
}
}
LL sum=0;
LL ans=0;
int up=a+k*t+MID;
int down=b-k*t+MID;
for(int i=down;i<=up;i++)
{
ans=(ans+dp1[t][i]*sum)%MOD;
sum=(sum+dp2[t][i])%MOD;
}
ans=(ans+MOD)%MOD;
printf("%lld\n",ans);
return 0;
}