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)^ ...
随机推荐
- Influxdb原理详解
本文属于<InfluxDB系列教程>文章系列,该系列共包括以下 15 部分: InfluxDB学习之InfluxDB的安装和简介 InfluxDB学习之InfluxDB的基本概念 Infl ...
- MemoryStream和FileStream
一,FileStream对象的数据来自文件,而MemoryStream对象的数据来自内存缓冲区.这两个类都继承自Stream类. 二,抽象基类System.IO.Stream代表流,它提供Read和W ...
- HMM 前向后向算法(转)
最近研究NLP颇感兴趣,但由于比较懒,所以只好找来网上别人的比较好的博客,备份一下,也方便自己以后方便查找(其实,一般是不会再回过头来看的,嘿嘿 -_-!!) 代码自己重新写了一遍,所以就不把原文代码 ...
- JAVA-代理学习一之JDK实现
代理的实现依赖于反射,建议不太懂反射的童鞋先看看反射相关的知识点. 代理可以理解为对实际调用方法的一种能力的加强. 代理分为静态代理和动态代理: <1> 静态代理示例 接口MyInterf ...
- js在关闭页面前弹出确认提示【转载】
最近项目中出现个bug,就是导出数据后,会提示确认导航,其实实际需求并不需要这个提示,可能是之前遗留的问题.查了下资料是在触发了onbeforeunload事件,那么剩下的就是代码组织问题了. 众所周 ...
- zabbix 布署实践【5 使用邮箱SMTP SSL推送告警邮件】
由于传统的邮件推送脚本使用smtp 25端口,在各大邮箱提供商已不适用,已经向SSL过渡,这里以QQ邮箱为例,使用SSL 465端口 登录zabbix-server 进入 cd /usr/lib/za ...
- LoRaWAN_stack移植笔记(一)--RF硬件相关
和硬件相关的问题 TCXO 的使用 根据SX1276数据手册, 如果使用TCXO,则需要配置RegTcxo寄存器为0x19,代码如下 ``` c void SX1276SetTcxoConfig(vo ...
- Android使用 startActivityForResult 、 onActivityResult 时的注意事项
今天使用 startActivityForResult 时遇到两个问题,应该是常见问题了吧,浪费了些时间才搞定,做个记录. 1. onActivityResult 的触发顺序问题 这个问题很郁闷,我一 ...
- [HMLY]6.iOS Xcode全面剖析
一.创建一个新工程 1.第一步打开Xcode,找到Xcode程序图标并点击 2.如下界面,我们点击新建一个项目,即第二项 (1).Get started with a playground playg ...
- 【JS】倒计时
描述: 先要链接jquery.js,这样写法可以直接放JS文件运行. //放在图片里定位的倒计时 //顶图里面定位才使用的代码 document.writeln("<style> ...