题解 | #Memory and Scores#

Memory and Scores

https://ac.nowcoder.com/acm/problem/111634

链接:https://ac.nowcoder.com/acm/problem/111634
来源:牛客网

题目描述 
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
输入
复制
1 2 2 1
输出
复制
6
示例2
输入
复制
1 1 1 2
输出
复制
31
示例3
输入
复制
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.

算法 动态规划-线性DP

让我们来翻译一下题意: 一个人初始分数是b-a,他一共做2t轮游戏,每一次游戏都从[-k,k]中选取一个数然后自己的分数加上这个数,求这个人在2t轮游戏结束后分数在0以上的方案数

f[i][j]表示第i轮后分数为j的方案数,有 f[i][j]=f[i1][jk]+...+f[i1][j+k]f[i][j] = f[i-1][j-k]+...+f[i-1][j+k] 由于当前层的状态由上一层得出,因此层数这一维我们可以直接省去,(类似于背包的空间优化) 有f[j]=f[jk]+...+f[j+k]=s[j+k]s[jk1]f[j] = f[j-k]+...+f[j+k] = s[j+k] - s[j-k-1] 其中我们每次求出f[i]的前缀和s[i]来加速求和;

此外还有一个问题就是每一次取负数值可能会导致出现负数下标,因此我们给整体加上一个偏移量delta = 2*t*k即可,于是下标0便是对应2tk,整个动态规划数组大小也就要开到21002*1000以上就行了;

#include<unordered_set>
#include<unordered_map>
#include<functional>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<set>
#include<map>

using namespace std;
//================================
#define debug(a) cout << #a": " << a << endl;
#define rep(i, ll,rr) for(int i = ll; i <= rr; ++i)
#define N 410010
const int mod = 1e9+7;
//================================
typedef pair<int,int> pii;
#define x first
#define y second
typedef long long LL; typedef unsigned long long ULL; typedef long double LD;
inline LL read() { LL s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar())    s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; }
inline void print(LL x, int op = 10) { if (!x) { putchar('0'); if (op)  putchar(op); return; }  char F[40]; LL tmp = x > 0 ? x : -x; if (x < 0)putchar('-');  int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';     tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]);    if (op) putchar(op); }
//================================= 
int a,b,k,t;
int delta,f[N],s[N],v;
long long ans=0;

void solve(){
	for(int i=1;i<=2*t;i++){
		s[0] = f[0];
		for(int i=1;i<=delta*2+k;i++) s[i] = (s[i-1]+f[i])%mod;
		for(int i=0;i<=k;i++) f[i] = s[i+k];
		for(int i=k+1;i<=delta*2;i++) f[i] = ((s[i+k] - s[i-k-1])%mod+mod)%mod;
	}
	for(int i=delta-a+b+1;i<=delta*2;i++) ans=(ans+f[i])%mod;
	print(ans);
}

//=================================
int main(){
	a = read(),b = read(),k = read(),t = read();
    v = b-a , delta = 2*k*t , f[delta] = 1 ;
    solve();    
	return 0;
}
全部评论

相关推荐

02-10 13:41
西南大学 Java
点赞 评论 收藏
分享
当年还在美团那个倒霉的&nbsp;Peppr&nbsp;团队工作时,我一直有个疑问:这群人每天到底在自嗨什么。每次开会一堆人围着一堆“看起来很高级”的文档转,模板统一、名词复杂、页数感人,每一页都在暗示一件事:“你不懂,是因为你不专业。”但现实是——代码照样写在&nbsp;💩&nbsp;山上,该出问题还是会出问题,这真的很逗,系统一出问题,文档的唯一作用就是证明:“我们当初确实认真写过文档。”所以本质区别到底是什么?是代码质量提升了,还是大家在精神层面完成了一次“工程师&nbsp;cosplay”?有句话说得好潮水退去才知道谁在裸泳。还记得当时的马哥、明哥(图&nbsp;1&nbsp;左)最爱反复强调一句话:“所有场景一定要想到。”、“这个场景为什么没考虑到?”不过他们这些话我是真的听进去了。不然我也不会在一年多前就说:这个项目活不过两年。顺带一提,那段时间还有个固定节目。每次下楼,总能听见我明哥在吐槽不同的人。我从他身后绕过去,经常能听到他一边抽烟一边说:“xx&nbsp;这小子太坑了,回头我一定要跟马哥说说。”于是深谙人情世故但真不会抽烟的我也会从口袋掏出一支低尼古丁含量的烟给自己点上,假意自己什么都没听到什么都不知道,只是来抽烟的。后来我才明白,这可能也是团队文化的一部分:问题永远在别人身上,而我们,永远在复盘里😂。
秋招白月光
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务