关于CSU 1725以及CodeForce 148D自己的解法
2016-08-03 11:10
253 查看
老实说那几天自己还不会概率DP,就按照自己的野路子来了。。但是发现也还是能够做出来,时间也和别人的差不多。。
感觉忘记太可惜了,于是特此记录下来。
数据结构:队列
例题:CSU 1725
我一开始的想法是用一个五维数组来表示,double arr[a][b][c][d][e] ,a表示余剩攻击次数,b表示余剩血量,c,d,e分别表示余剩的1,2,3血的奴隶主,而 arr[a][b][c][d][e]储存的是发生这个局面的概率。
由一个局面到达另外一个局面的情况只有5种,攻击英雄致死,攻击英雄未致死,攻击一血奴隶主,攻击二血奴隶主并产生一个新的,攻击二血奴隶主
未产生新的,攻击三血的情况同攻击二血的。
因此,我采用一个结构体Node,Node有5个数据成员,含义同五维数组的下标,当首先把最初的局面加入队列,然后通过不断的取队列的front来不断推演,停止演算的条件是英雄血量为0或者是余剩次数为0
接下来发生的局面,并且同时更新arr五维数组,也就是说,最终在五维数组里面储存的是各个局面发生的概率,我只需要把这个五维数组遍历一遍,取出我想要的局面的 概率,都加起来即可。
PS:flag数组的含义和SPFA里面的一个bool数组差不多,用于表示某一个局面是否已经在队列中存在。
代码:(在所有AC的人里面,我的代码是最长的。。。。。)
CodeForce 148D:原来是是一个龙和公主抓老鼠的故事,这种事情当然是要公主赢才是。。而且公主的意见也很不错呀。。龙为什么就不听话呢。。。
扯远了。。咳咳,下面是正题
同样的,使用一个结构体来表示到达这个局面的概率,然后数组更新完毕之后,回过头去,在每一种状态的下算一遍公主胜利的概率。
至于局面终止的情况,就是没有白色的老鼠了
以上,自己的野套路讲解完毕
感觉忘记太可惜了,于是特此记录下来。
数据结构:队列
例题:CSU 1725
我一开始的想法是用一个五维数组来表示,double arr[a][b][c][d][e] ,a表示余剩攻击次数,b表示余剩血量,c,d,e分别表示余剩的1,2,3血的奴隶主,而 arr[a][b][c][d][e]储存的是发生这个局面的概率。
由一个局面到达另外一个局面的情况只有5种,攻击英雄致死,攻击英雄未致死,攻击一血奴隶主,攻击二血奴隶主并产生一个新的,攻击二血奴隶主
未产生新的,攻击三血的情况同攻击二血的。
因此,我采用一个结构体Node,Node有5个数据成员,含义同五维数组的下标,当首先把最初的局面加入队列,然后通过不断的取队列的front来不断推演,停止演算的条件是英雄血量为0或者是余剩次数为0
接下来发生的局面,并且同时更新arr五维数组,也就是说,最终在五维数组里面储存的是各个局面发生的概率,我只需要把这个五维数组遍历一遍,取出我想要的局面的 概率,都加起来即可。
PS:flag数组的含义和SPFA里面的一个bool数组差不多,用于表示某一个局面是否已经在队列中存在。
代码:(在所有AC的人里面,我的代码是最长的。。。。。)
#include<iostream> #include<queue> #include<cstring> using namespace std; int t,x,y,z,num; struct Node{ int times,health,num1,num2,num3; Node(int e=0,int a=0,int b=0,int c=0,int d=0):times(e),health(a),num1(b),num2(c),num3(d){}; }te; queue<Node> q; double arr[25][25][8][8][8],probaboly; bool flag[25][25][8][8][8]; int main(){ ios_base::sync_with_stdio(false); cout.setf(ios_base::fixed); cout.precision(6); cin>>t; while(t--){ cin>>x>>y>>z; if(x<y) cout<<"0.000000\n"; else{ arr[x][y][0][0][z]=1;q.push({x,y,0,0,z}); flag[x][y][0][0][z]=true; while(!q.empty()){ te=q.front();q.pop();flag[te.times][te.health][te.num1][te.num2][te.num3]=false; //cout<<te.times<<' '<<te.health<<' '<<te.num1<<' '<<te.num2<<' '<<te.num3<<endl; if(te.health==0) continue; if(te.times!=0){ num=1+te.num1+te.num2+te.num3; if(te.health!=0){ arr[te.times-1][te.health-1][te.num1][te.num2][te.num3]+=arr[te.times][te.health][te.num1][te.num2][te.num3]/num; if(!flag[te.times-1][te.health-1][te.num1][te.num2][te.num3]) q.push({te.times-1,te.health-1,te.num1,te.num2,te.num3}),flag[te.times-1][te.health-1][te.num1][te.num2][te.num3]=true; } if(te.num1!=0){ arr[te.times-1][te.health][te.num1-1][te.num2][te.num3]+=arr[te.times][te.health][te.num1][te.num2][te.num3]*te.num1/num; if(!flag[te.times-1][te.health][te.num1-1][te.num2][te.num3]) q.push({te.times-1,te.health,te.num1-1,te.num2,te.num3}),flag[te.times-1][te.health][te.num1-1][te.num2][te.num3]=true; } if(te.num2!=0){ if(num<8){ arr[te.times-1][te.health][te.num1+1][te.num2-1][te.num3+1]+=arr[te.times][te.health][te.num1][te.num2][te.num3]*te.num2/num; if(!flag[te.times-1][te.health][te.num1+1][te.num2-1][te.num3+1]) q.push({te.times-1,te.health,te.num1+1,te.num2-1,te.num3+1}),flag[te.times-1][te.health][te.num1+1][te.num2-1][te.num3+1]=true; } else{ arr[te.times-1][te.health][te.num1+1][te.num2-1][te.num3]+=arr[te.times][te.health][te.num1][te.num2][te.num3]*te.num2/num; if(!flag[te.times-1][te.health][te.num1+1][te.num2-1][te.num3]) q.push({te.times-1,te.health,te.num1+1,te.num2-1,te.num3}),flag[te.times-1][te.health][te.num1+1][te.num2-1][te.num3]=true; } } if(te.num3!=0){ if(num<8){ arr[te.times-1][te.health][te.num1][te.num2+1][te.num3]+=arr[te.times][te.health][te.num1][te.num2][te.num3]*te.num3/num; if(!flag[te.times-1][te.health][te.num1][te.num2+1][te.num3]) q.push({te.times-1,te.health,te.num1,te.num2+1,te.num3}),flag[te.times-1][te.health][te.num1][te.num2+1][te.num3]=true; } else{ arr[te.times-1][te.health][te.num1][te.num2+1][te.num3-1]+=arr[te.times][te.health][te.num1][te.num2][te.num3]*te.num3/num; if(!flag[te.times-1][te.health][te.num1][te.num2+1][te.num3-1]) q.push({te.times-1,te.health,te.num1,te.num2+1,te.num3-1}),flag[te.times-1][te.health][te.num1][te.num2+1][te.num3-1]=true; } } } } for(int m=x-y;m>=0;--m) for(int i=0;i<=7;++i) for(int j=0;j<=7-i;++j) for(int k=0;k<=7-i-j;++k) probaboly+=arr[m][0][i][j][k];//,cout<<m<<' '<<i<<' '<<j<<' '<<k<<' '<<arr[m][0][i][j][k]<<endl; //cout<<arr[0][0][0][0][1]<<' '<<arr[0][0][0][1][1]<<endl; cout<<probaboly<<endl;memset(arr,0,sizeof(arr));probaboly=0;//memset(flag,0,sizeof(flag)); } } return 0; }
CodeForce 148D:原来是是一个龙和公主抓老鼠的故事,这种事情当然是要公主赢才是。。而且公主的意见也很不错呀。。龙为什么就不听话呢。。。
扯远了。。咳咳,下面是正题
同样的,使用一个结构体来表示到达这个局面的概率,然后数组更新完毕之后,回过头去,在每一种状态的下算一遍公主胜利的概率。
至于局面终止的情况,就是没有白色的老鼠了
#include<cstdio> #include<queue> #include<cstring> using namespace std; int w,b; double arr[1010][1010],sum; struct Node{ int w,b; Node(int a =0,int c=0):w(a),b(c){}; }te; bool flag[1010][1010]; queue<Node> q; int main(){ while(scanf("%d",&w)!=EOF){ scanf("%d",&b); arr[w][b]=1;q.push({w,b}); while(!q.empty()){ te=q.front();q.pop();flag[te.w][te.b]=false; if(te.w&&!te.b)continue; if(te.w>0&&te.b>1){ arr[te.w-1][te.b-2]+=arr[te.w][te.b]*te.b/(te.b+te.w)*(te.b-1)/(te.b+te.w-1)*te.w/(te.b+te.w-2); if(!flag[te.w-1][te.b-2]) q.push({te.w-1,te.b-2}),flag[te.w-1][te.b-2]=true; } if(te.b>2){ //printf("%lf %lf ",arr[te.w][te.b-3],arr[te.w][te.b]*te.b/(te.w+te.b)*(te.b-1)/(te.b+te.w-1)*(te.b-2)/(te.b+te.w-2)); arr[te.w][te.b-3]+=arr[te.w][te.b]*te.b/(te.w+te.b)*(te.b-1)/(te.b+te.w-1)*(te.b-2)/(te.b+te.w-2); //printf("%lf",arr[1][0]); if(!flag[te.w][te.b-3]) q.push({te.w,te.b-3}),flag[te.w][te.b-3]=true; } } for(int i=1;i<=w;++i){ for(int j=0;j<=b;++j) sum+=arr[i][j]*i/(i+j);//,printf("%lf %d %d ",arr[i][j],i,j); } printf("%.9lf\n",sum);sum=0;memset(arr,0,sizeof(arr)); } }
以上,自己的野套路讲解完毕
相关文章推荐
- 强迫自己学习(实践篇),以及关于写博客的几点建议
- 关于telnet协议的研究以及用java进行封装实现自己的telnet客户端
- 关于使用eclipse自带的maven插件以及使用自己安装maven插件
- pat中关于并查集的题目&&以及类似dfs解法
- 关于职业规划以及工作经验积累的想法——说给你自己听的话
- 关于使用eclipse自带的maven插件以及使用自己安装maven插件
- 关于function declared implicitly的正确解法以及extern的用法
- 关于imageview 不让背景图片自动拉伸填充 imageview 以及布局参数的设置的小结(自己试验的可能不怎么准确)
- 关于Scroller的使用以及自己实现一个侧滑菜单
- 关于短信的读取以及新短信到达时如何触发事件去处理自己的逻辑
- 关于使用eclipse自带的maven插件以及使用自己安装maven插件
- 关于使用eclipse自带的maven插件以及使用自己安装maven插件
- 强迫自己学习(实践篇),以及关于写博客的几点建议
- 关于tomcat端口的修改,以及同时部署多个应用,自己遇到的问题以及解决办法
- 关于如何在Android源码目录中建立自己的C工程,并用mm命令单独进行该C工程模块的编译,以及Android.mk的使用介绍(2)
- 关于ValueAnimation以及Interpolator +Drawable实现的自己定义动画效果
- 强迫自己学习(实践篇),以及关于写博客的几点建议
- 关于终端和控制台,以及自己的测试
- 关于如何制作自己的Java第三方类库,以及如何制作自己类库的Javadoc
- 写给自己,关于对纯技术的追求,以及为了金钱与前途的技术追求