Memory and Scores
Memory and Scores
题目链接:http://codeforces.com/contest/712/problem/D
dp
因为每轮Memory和Lexa能取的都在[-k,k],也就是说每轮两人分数的变化量在[-2k,2k];
故可以定义状态:dp[times][diff]为第times次Memory和Lexa的分数差为diff的方案数.
而dp[times][diff]可以从dp[times-1][diff-2k]到dp[times-1][diff+2k]转移而来;
又因为变化量为-2k时的方案数为1(-k,k),
变化量为-2k+1时的方案数为2(-k,k-1;-k+1,k),
变化量为-2k+2时的方案数为3(-k,k-2;-k+1,k-1;-k+2,k),
...,
变化量为-2k+m时的方案数为m+1,
...,
变化量为0时的方案数为2k+1,
...,
变化量为2k-m时的方案数为m+1,
...,
变化量为2k-1时的方案数为2,
变化量为2k时的方案数为1.
所以状态转移方程为:dp[times][diff]=dp[times-1][diff-2k]+2*dp[times-1][diff-2k+1]+3*dp[times-1][diff-2k+2]+...+(m+1)*dp[times-1][diff-2k+m]+...+2*dp[times-1][diff+2k-1]+dp[times-1][diff+2k];
这样的话,时间复杂度为O(k2t2),代码如下:
#include<iostream>
#include<cmath>
#define M 1000000007LL
#define TIME 105
#define DIFF 300000
#define BASE 150000
using namespace std;
typedef long long LL;
LL a,b,k,t,ans;
LL dp[TIME][DIFF];
int main(void){
cin>>a>>b>>k>>t;
dp[][a-b+BASE]=;
LL upper=a-b+BASE+*k*t;
LL lower=a-b+BASE-*k*t;
for(LL times=;times<=t;++times){
for(LL diff=lower;diff<=upper;diff++){
for(LL m=;m<=*k;m++){
LL add=-*k+m;
if(diff+add>=lower){
if(add)dp[times][diff]+=(dp[times-][diff+add]+dp[times-][diff-add])*(m+);
else dp[times][diff]+=dp[times-][diff]*(m+);
dp[times][diff]%=M;
}
}
}
}
for(int i=BASE+;i<=upper;++i)
ans=(ans+dp[t][i])%M;
cout<<ans<<endl;
}
很显然,这会T,所以必须做出优化。
注意到:
dp[times][diff]是在dp[times][diff-1]的基础上前半段各个项减一,后半段各个项加一得到的,所以可以维护一个前缀和数组pre[i],那么
dp[times][diff]=dp[times][diff-1]+(pre[diff+2k]-pre[diff-1])-(pre[diff-1]-pre[(diff-1)-2k-1])
可以在O(1)的时间内完成,优化后的代码时间复杂度为O(kt2),代码如下:
#include<iostream>
#include<cmath>
#define M 1000000007LL
#define TIME 105
#define DIFF 500000
#define BASE 250000
using namespace std;
typedef long long LL;
LL a,b,k,t,ans;
LL dp[TIME][DIFF];
LL pre[DIFF];
int main(void){
cin>>a>>b>>k>>t;
dp[][a-b+BASE]=;
LL upper=a-b+BASE+*k*t;
LL lower=a-b+BASE-*k*t;
for(LL times=;times<=t;++times){
for(LL diff=lower;diff<=upper;diff++)
pre[diff]=pre[diff-]+dp[times-][diff],pre[diff]%=M;
for(LL m=;m<=*k;m++){
LL add=-*k+m;
if(add)dp[times][lower]
+=(dp[times-][lower+add]+dp[times-][lower-add])*(m+);
else dp[times][lower]+=dp[times-][lower]*(m+);
dp[times][lower]%=M;
}
for(LL diff=lower+;diff<=upper;diff++){
dp[times][diff]=dp[times][diff-]
+(pre[min(upper,diff+*k)]-pre[diff-])
-(pre[diff-]-pre[max(lower,diff--*k)-]);
dp[times][diff]=(dp[times][diff]+M)%M;
//记得+M,减法模运算可能会出现负数
}
}
for(int i=BASE+;i<=upper;++i)
ans=(ans+dp[t][i])%M;
cout<<ans<<endl;
}
这样的代码仍然可以优化:
1.可以用滚动数组来优化空间复杂度,从O(kt2)降低到O(kt),太懒没写╮(╯▽╰)╭;
2.可以用快速傅里叶变换FFT优化时间复杂度,从O(kt2)继续降到O(kt lg(kt)),没学还不会写╮(╯▽╰)╭
//昨天去面试微软俱乐部被嘲讽=。= 定个目标吧,这学期div2稳定4题怎么样?
Memory and Scores的更多相关文章
- Codeforces Round #370 (Div. 2) D. Memory and Scores DP
D. Memory and Scores Memory and his friend Lexa are competing to get higher score in one popular c ...
- Codeforces Round #370 (Div. 2) D. Memory and Scores 动态规划
D. Memory and Scores 题目连接: http://codeforces.com/contest/712/problem/D Description Memory and his fr ...
- [Codeforces712D] Memory and Scores(DP+前缀和优化)(不用单调队列)
[Codeforces712D] Memory and Scores(DP+前缀和优化)(不用单调队列) 题面 两个人玩游戏,共进行t轮,每人每轮从[-k,k]中选出一个数字,将其加到自己的总分中.已 ...
- 【26.87%】【codeforces 712D】Memory and Scores
time limit per test2 seconds memory limit per test512 megabytes inputstandard input outputstandard o ...
- [CodeForces - 712D]Memory and Scores (DP 或者 生成函数)
题目大意: 两个人玩取数游戏,第一个人分数一开始是a,第二个分数一开始是b,接下来t轮,每轮两人都选择一个[-k,k]范围内的整数,加到自己的分数里,求有多少种情况使得t轮结束后a的分数比b高. ( ...
- Codeforces 712 D. Memory and Scores (DP+滚动数组+前缀和优化)
题目链接:http://codeforces.com/contest/712/problem/D A初始有一个分数a,B初始有一个分数b,有t轮比赛,每次比赛都可以取[-k, k]之间的数,问你最后A ...
- CodeForces 712D Memory and Scores
$dp$,前缀和. 记$dp[i][j]$表示$i$轮结束之后,两人差值为$j$的方案数. 转移很容易想到,但是转移的复杂度是$O(2*k)$的,需要优化,观察一下可以发现可以用过前缀和来优化. 我把 ...
- CF370 D Memory and Scores
dp题 并运用了前缀和 我看题目提示中有fft 我想了下感觉复杂度不过关还是未解 #include<bits/stdc++.h> using namespace std; typedef ...
- CF712D Memory and Scores
题目分析 实际上两个人轮流取十分鸡肋,可以看作一个人取2t次. 考虑生成函数. 为了方便,我们对取的数向右偏移k位. 取2t次的生成函数为: \[ F(x)=(\sum_{i=0}^{2k}x_i)^ ...
随机推荐
- iOS开发-内存管理
内存管理 对于这篇呢,其实现在都是ARC模式,正常状态下基本不用我们去手动释放内存,所以如果不是要面试呀.装逼或者扎实功底的,就先别看了或者了解下即可,因为像面试时,有些面试官想看你的基础时,就有些人 ...
- SAP CRM 为用户创建业务合作伙伴并分配到组织单位
想要在SAP CRM的前台完成一些操作,需要登录的用户在系统中存在对应的业务合作伙伴才可以,某些情况下,还需要被分配到正确的公司.部门.职位.下面是相关的操作步骤. 本文假定读者已经拥有一个开发帐号. ...
- overflow属性及其在ios下卡顿问题解决
overflow属性:http://www.w3school.com.cn/cssref/pr_pos_overflow.asp overflow:scroll/auto;在手机页面滑动不流畅问题: ...
- 校门外的树 OpenJudge 1.6.06
06:校门外的树 总时间限制: 1000ms 内存限制: 65536kB 描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0 ...
- maven之(六)setting.xml的配置文件详解
setting.xml配置文件 maven的配置文件settings.xml存在于两个地方: 1.安装的地方:${M2_HOME}/conf/settings.xml 2.用户的目录:${user.h ...
- [SOJ] 简单哈希
Description 使用链地址法(又称拉链法)可以解决Hash中的冲突问题.其基本思想是:将具有相同哈希地址的记录链成一个单链表,m个哈希地址就设m个单链表,然后用一个数组将m个单链表的表头指针存 ...
- Python中is和==的区别的
在python中,is检查两个对象是否是同一个对象,而==检查他们是否相等. str1 = 'yangshl' str2 = 'yang' + 'shl' print('str1 == str2:', ...
- 工具-maya2014软件操作细节(持续更新……)
整体 ------------------------------------------------------- [全选控制器] 1.选中总控-显示-隔离选择-查看选定对象 2.全选并创建新层(不 ...
- Android开源库loopj的android-async-http的 JsonHttpResponseHandler 存在死循环GC_CONCURRENT
我现在用的是 AndroidAsyncHttp 1.4.4 版本,之前遇到一个很奇怪的问题, 当使用 JsonHttpResponseHandler 解析请求的页面出现服务器错误或其他情况返回的内容不 ...
- CodeForces 659F Polycarp and Hay
并查集,$dfs$. 从大的数字往里加,每加一个数字合并一下连通块,判断连通块内数字个数是否够,以及k能不能被当前加入的数字整除.然后$dfs$一下构造答案. #pragma comment(link ...