[JZOJ3168] 【GDOI2013模拟3】踢足球
题目
描述
题目大意
有两个队伍,每个队伍各nnn人。
接到球的某个人会再下一刻随机地传给自己人、敌人和射门,射门有概率会中。
每次射门之后球权在对方111号选手。
某个队伍到了RRR分,或者总时间到达TTT时,比赛结束。
询问每种比分的概率。
思考历程
一看就觉得这是一道DP
设一个五维的状态,其中两维表示比分,一维表示时间,一维表示分数,还有一维表示球权。
不得不说这是最粗暴的方法。
接着呢……想了很久就没有去想了,甚至连暴力也没有打。
正解
正解还是DP。
我们试着给DP降维打击,机智的DYP大佬就想到了省去球权的这一维。
因为题目有个重要的性质:当一个球队射门之后,球权必定在对方的111号选手。
我们设fr1,r2,t,0/1f_{r1,r2,t,0/1}fr1,r2,t,0/1表示概率,r1r1r1和r2r2r2表示比分,ttt表示时间,后面的表示球权在哪个队(的111号选手)。
让我们考虑一下从发球到其中一个队进球这个过程为单位的转移。
我们再设g0/1,0/1,tg_{0/1,0/1,t}g0/1,0/1,t表示某个队发球,某个队进球,花了ttt时间的概率。
于是我们就可以通过ggg来求出fff了。
接着问题变成了如何求ggg。
还是DP。
设h0/1,t,ih_{0/1,t,i}h0/1,t,i表示从某个队发球,花了ttt时间,球权在iii的概率。
在DP转移hhh时,如果射门就会转移到ggg,否则还是转移到hhh。
这样题目就基本做完了。
注意一点,在统计答案的时候,对于双方比分都没有到达RRR的情况,我们需要枚举时间,用对应的fff值乘上在剩下时间中不进球的概率。
显然,这个不进球的概率就是对应时间中hhh值的和。
代码
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#define N 110
#define maxR 11
#define maxT 501
int n,R,T;
double score[N*2],p[N*2];
int e[N*2][N*2];
double h[2][maxT][N*2],g[2][2][maxT],f[maxR][maxR][maxT][2];
double sumh[2][maxT];
int main(){
scanf("%d%d%d",&n,&R,&T);
for (int i=1;i<=n;++i){
scanf("%lf",&score[i]);
int k1,k2;scanf("%d%d",&k1,&k2);
for (int j=1;j<=k1;++j){
int x;scanf("%d",&x);
e[i][x]=1;
}
for (int j=1;j<=k2;++j){
int x;scanf("%d",&x);
e[i][n+x]=1;
}
p[i]=1.0/(k1+k2+1);
}
for (int i=n+1;i<=2*n;++i){
scanf("%lf",&score[i]);
int k1,k2;scanf("%d%d",&k1,&k2);
for (int j=1;j<=k1;++j){
int x;scanf("%d",&x);
e[i][n+x]=1;
}
for (int j=1;j<=k2;++j){
int x;scanf("%d",&x);
e[i][x]=1;
}
p[i]=1.0/(k1+k2+1);
}
for (int st=0;st<=1;++st){
h[st][0][st*n+1]=1;
for (int j=0;j<T;++j)
for (int k=1;k<=2*n;++k){
if (k<=n){
g[st][0][j+1]+=h[st][j][k]*p[k]*score[k];
h[st][j+1][n+1]+=h[st][j][k]*p[k]*(1-score[k]);
}
else{
g[st][1][j+1]+=h[st][j][k]*p[k]*score[k];
h[st][j+1][1]+=h[st][j][k]*p[k]*(1-score[k]);
}
for (int l=1;l<=2*n;++l)
if (e[k][l])
h[st][j+1][l]+=h[st][j][k]*p[k];
}
for (int j=0;j<=T;++j)
for (int k=1;k<=2*n;++k)
sumh[st][j]+=h[st][j][k];
}
f[0][0][0][0]=1;
for (int i=0;i<R;++i)
for (int j=0;j<R;++j)
for (int k=0;k<T;++k)
for (int t=1;k+t<=T;++t){
f[i][j+1][k+t][0]+=f[i][j][k][0]*g[0][1][t]+f[i][j][k][1]*g[1][1][t];
f[i+1][j][k+t][1]+=f[i][j][k][0]*g[0][0][t]+f[i][j][k][1]*g[1][0][t];
}
for (int i=0;i<=R;++i)
for (int j=0;j<=R;++j){
double ans=0;
if (i<R && j<R){
for (int k=0;k<=T;++k)
ans+=f[i][j][k][0]*sumh[0][T-k]+f[i][j][k][1]*sumh[1][T-k];
}
else{
if (i==R && j==R)
break;
for (int k=0;k<=T;++k)
ans+=f[i][j][k][0]+f[i][j][k][1];
}
printf("%.8lf\n",ans);
}
return 0;
}
总结
有时候一个DP不能解决,就用两个DP,如果两个DP不能解决,那就三个……
[JZOJ3168] 【GDOI2013模拟3】踢足球的更多相关文章
- 【JD的一人戏】之"小羊踢足球"第一篇
好多次加班后坐的士回家,副驾驶座位后内嵌的显示屏正好在播放一个美食节目,内容就是一个着装怪异的厨子把各种食材分门别类地摆在你面前,然后用小小的锅碗瓢盆慢慢的做出很精致的够一个人吃的分量的各种美食,做好 ...
- 当会打王者荣耀的AI学会踢足球,一不小心拿下世界冠军!
难得的元旦小假期,没有什么比得上在慵懒的冬日艳阳下放松自己,拿起手机,叫上了许久未一起作战的小伙伴,到王者荣耀中激战了一番,仿佛又回到了当年那个年轻的自己. 厉害不,毕竟当年DD也是王者五十星的水平, ...
- jzoj3156. 【GDOI2013模拟1】病毒传播
题意: 村庄里有m个人,初始有一些人感染了病毒.如果第i个人的编号i满足,有一对(a,b)(a是初始病毒感染者编号,b为前一天的感染者编号)使\(a*b mod m =i\),则第i个人会感染病毒.每 ...
- 【GDOI2013模拟4】贴瓷砖
题目 A镇的主街是由N个小写字母构成,镇长准备在上面贴瓷砖,瓷砖一共有M种,第i种上面有Li个小写字母,瓷砖不能旋转也不能被分割开来,瓷砖只能贴在跟它身上的字母完全一样的地方,允许瓷砖重叠,并且同一种 ...
- [JZOJ3167] 【GDOI2013模拟3】查税
题目 描述 题目大意 维护一个有一次函数组成的序列 具体来说,对于位置xxx,现在的值为sx+zx∗(T−tx)s_x+z_x*(T-t_x)sx+zx∗(T−tx) 有两个操作,修改某个位置上 ...
- [JZOJ3171] 【GDOI2013模拟4】重心
题目 描述 题目大意 有一堆长为222的矩形,最下面的右端点横坐标为000. 每个矩形都有其固定的质量. 将这些矩形堆在一起,使得最右边的横坐标最大,并且满足它不会塌掉(满足物理学). 思考历程 首先 ...
- [JZOJ3177] 【GDOI2013模拟5】安全监控
题目 描述 (样例都懒得发出来了) 题目大意 给你一个有向图,从111号点出发,绕一圈回来.这一圈中必须经过222号点. 问经过的最少的点数(不重复). 思考历程 一看就觉得是一道神题. 然后仔细观察 ...
- [JZOJ3187]【GDOI2013模拟8】的士
题目 描述 题目大意 在一个数轴上,有些人要从某个点到达另一个点. 出租车从最左端出发,将所有人送到它们的目的地,最终到达最右边的点. 出租车只能做一个乘客,并且可以在图中将乘客丢下. 问最短时间. ...
- 足球运动训练心得及经验分析-c语言学习调查
在准备预备作业02之前,我参考娄老师的提示,阅读了<[做中学(Learning By Doing)]之乒乓球刻意训练一年总结>一文. 在文章描述的字里行间,给予我的印象是系统.负责,娄老师 ...
随机推荐
- [17]APUE:线程
通常情况下,线程模型的并发性能优于进程模型,但不总是这样 线程的优势: 线程的创建.销毁及上下文切换代价比进程低 某些情况下,使用线程可以简化逻辑,避免异步编程的复杂性 同一进程内所有线程共享全局内存 ...
- nodejs--express安装失败的原因
1.检查更新所有的npm ,jade,或者ejs. 2.在用jade或ejs也是有区别的,jade适合个人秀,ejs更实用与商务. 3.express在4.+之后的版本都分离了,推荐用3.+的版本稳定 ...
- **JLink Warning: Mis-aligned memory write: Address: 0x20000000, NumBytes: 2, Alignment: 2 (Halfword-aligned)
网上也有同学遇到这个问题,http://www.openedv.com/thread-113049-1-3.html 根据他的经验我也重新安装了Jlink驱动: 顺便注意Dialog DLL:TARM ...
- 使用kubeadm安装kubernetes 1.15
1.主机准备篇 使用vmware Workstation 10创建一台虚拟机,配置为2C/2G/50G,操作系统为CentOS Linux release 7.6.1810 (Core). IP地址为 ...
- 解决WIN8输入法的问题,Ctrl+空格,Ctrl+Shift,切换问题
在WIN8中,我们曾经熟悉的的Ctrl+空格和Ctrl+Shift消失了,取而导致的是WIN+空格. 在这里先简单解释一下WIN8的输入法结构: 在WIN7以前的输入法中,输入法采用了平行目录的结构, ...
- Winform打包工具SetupFactory 9 的使用 (转)
写了个WinForm的小程序..以前没打过包..只是直接把Bin里的东西复制出来使用..自己使用是足够.但是发给别人毕竟不太好看(不牛逼)..所以就想着打包.. Vs2012自带的有打包的功能..相信 ...
- 几个实用的js函数
在阅读JavaScript DOM编程艺术这本书时看到了一些比较实用的代码. //加载多个window.onload事件 function addLoadEvent(func) { var oldon ...
- arm-linux-copydump 的使用
生成可以执行的 2 进制代码 [arm@localhost gcc]#armlinuxcopydump O binary hello hello.bin
- 【学术篇】SPOJ QTREE 树链剖分
发现链剖这东西好久不写想一遍写对是有难度的.. 果然是熟能生巧吧.. WC的dalao们都回来了 然后就用WC的毒瘤题荼毒了我们一波, 本来想打个T1 44分暴力 然后好像是特判写挂了还是怎么的就只能 ...
- FCC知识点总结
1.DOMContentLoaded事件 2.延迟脚本 defer 3.异步脚本async 4.[找最长单词]—— 找出句子中最长的单词,并返回它的长度. 5.数组slice().splice() s ...
