您的位置:首页 > 其它

[CF 712D] Memory and Scores

2016-10-09 20:43 369 查看

Description

有两个人在玩游戏,第一个人初始有a分,第二个人有b分。

总共玩t轮游戏,每一轮游戏每个人可以从[-k,k]中任选一个数,加进自己的分数中。

分数大的人获胜。

求有多少种情况先手获胜。

答案mod 1e9+7

1 ≤ a, b ≤ 100, 1 ≤ k ≤ 1000, 1 ≤ t ≤ 100

Solution

直觉告诉我这道题应该是有数学方法的,然而本蒟蒻不会。。。

那么就来Dp吧~

首先,每一轮游戏可以拆成两轮一样的游戏。

那么我们就相当于玩2t轮,每一轮两个人的分数差值会最大+k,最小-k

设Fi,j表示第i轮,两个人的分差为j的方案数。

那么Fi,j可以对Fi+1,j-k~Fi+1,j+k贡献。

如何快速地处理区间加?

差分然后前缀和呗~

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define N 400005
using namespace std;
const int mo=1e9+7;
int a,b,k,t,p,q,ans,f[2]
;
int main() {
scanf("%d%d%d%d",&a,&b,&k,&t);
int l=a-b-2*k*t,r=a-b+2*k*t;
f[0][a-b-l]=1;p=0;q=1;
fo(i,0,2*t-1) {
memset(f[q],0,sizeof(f[q]));
fo(j,l,r) if (f[p][j-l]) (f[q][j-l-k]+=f[p][j-l])%=mo,
(f[q][j-l+k+1]+=mo-f[p][j-l])%=mo;
fo(j,1,r-l+1) (f[q][j]+=f[q][j-1])%=mo;
p=q;q=1-p;
}
fo(i,1,r) (ans+=f[p][i-l])%=mo;
printf("%d",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: