HDU 4405 Aeroplane chess [概率DP+并查集]
2015-12-01 00:08
405 查看
Description
Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six faces with equal probability to face up and the numbers on the faces are
1,2,3,4,5,6). When Hzz is at grid i and the dice number is x, he will moves to grid i+x. Hzz finishes the game when i+x is equal to or greater than N.
There are also M flight lines on the chess map. The i-th flight line can help Hzz fly from grid Xi to Yi (0<Xi<Yi<=N) without throwing the dice. If there is another flight line from Yi, Hzz can take the flight line continuously. It is granted that there is
no two or more flight lines start from the same grid.
Please help Hzz calculate the expected dice throwing times to finish the game.
Input
There are multiple test cases.
Each test case contains several lines.
The first line contains two integers N(1≤N≤100000) and M(0≤M≤1000).
Then M lines follow, each line contains two integers Xi,Yi(1≤Xi<Yi≤N).
The input end with N=0, M=0.
Output
For each test case in the input, you should output a line indicating the expected dice throwing times. Output should be rounded to 4 digits after decimal point.
题意:
飞行棋盘长度为N+1,标号从0到N,中间有M条飞行线,可以从Xi直接飞到Yi(可以连续飞),现在丢骰子,问走到>=N的投掷期望次数。
范围:
N<=10W,M<=1000
解法:
很明显的概率DP,设DP[I]为当前站在I位置,走到头的期望投掷数为DP[I],显然DP[>=N]=0,目标为DP[0]
方程为 DP[I]=Σ (1/6 * DP[J]) ,其中J分别投出1-6会到达的点,这个点可以通过并查集求出。
代码:
Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six faces with equal probability to face up and the numbers on the faces are
1,2,3,4,5,6). When Hzz is at grid i and the dice number is x, he will moves to grid i+x. Hzz finishes the game when i+x is equal to or greater than N.
There are also M flight lines on the chess map. The i-th flight line can help Hzz fly from grid Xi to Yi (0<Xi<Yi<=N) without throwing the dice. If there is another flight line from Yi, Hzz can take the flight line continuously. It is granted that there is
no two or more flight lines start from the same grid.
Please help Hzz calculate the expected dice throwing times to finish the game.
Input
There are multiple test cases.
Each test case contains several lines.
The first line contains two integers N(1≤N≤100000) and M(0≤M≤1000).
Then M lines follow, each line contains two integers Xi,Yi(1≤Xi<Yi≤N).
The input end with N=0, M=0.
Output
For each test case in the input, you should output a line indicating the expected dice throwing times. Output should be rounded to 4 digits after decimal point.
题意:
飞行棋盘长度为N+1,标号从0到N,中间有M条飞行线,可以从Xi直接飞到Yi(可以连续飞),现在丢骰子,问走到>=N的投掷期望次数。
范围:
N<=10W,M<=1000
解法:
很明显的概率DP,设DP[I]为当前站在I位置,走到头的期望投掷数为DP[I],显然DP[>=N]=0,目标为DP[0]
方程为 DP[I]=Σ (1/6 * DP[J]) ,其中J分别投出1-6会到达的点,这个点可以通过并查集求出。
代码:
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<iostream> #include<stdlib.h> #include<set> #include<map> #include<queue> #include<vector> #include<bitset> #pragma comment(linker, "/STACK:1024000000,1024000000") template <class T> bool scanff(T &ret){ //Faster Input char c; int sgn; T bit=0.1; if(c=getchar(),c==EOF) return 0; while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); if(c==' '||c=='\n'){ ret*=sgn; return 1; } while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10; ret*=sgn; return 1; } #define inf 1073741823 #define llinf 4611686018427387903LL #define PI acos(-1.0) #define lth (th<<1) #define rth (th<<1|1) #define rep(i,a,b) for(int i=int(a);i<=int(b);i++) #define drep(i,a,b) for(int i=int(a);i>=int(b);i--) #define gson(i,root) for(int i=ptx[root];~i;i=ed[i].next) #define tdata int testnum;scanff(testnum);for(int cas=1;cas<=testnum;cas++) #define mem(x,val) memset(x,val,sizeof(x)) #define mkp(a,b) make_pair(a,b) #define findx(x) lower_bound(b+1,b+1+bn,x)-b #define pb(x) push_back(x) using namespace std; typedef long long ll; typedef pair<int,int> pii; int n,m; int f[100100]; int find(int x){ while(x!=f[x]){ f[x]=f[f[x]]; x=f[x]; } return x; } void connec(int x,int y){ int i=find(x); int j=find(y); if(i==j)return; if(i>j)swap(i,j); f[i]=j; } double dp[100100]; int main(){ while(scanf("%d%d",&n,&m)!=EOF){ if(n==0&&m==0)break; rep(i,1,n+10)f[i]=i; rep(i,1,m){ int x,y; scanff(x); scanff(y); connec(x,y); } rep(j,0,10)dp[n+j]=0; drep(i,n-1,0){ dp[i]=1.0; rep(j,1,6){ dp[i]+=dp[find(i+j)]/6.0; } } printf("%.4lf\n",dp[0]); } return 0; }
相关文章推荐
- 助你美化网站的实用css3技巧(1)
- python 统计tomcat access日志访问时延
- docker registry部署(容器化运行,ssl证书生成,nginx配置)
- 网站内连优化--内连建5设的几点建议
- Android平台架构及特性
- Tomcat线程池配置
- 路径 读取Properties文件
- 常见的高可用MySQL解决方案
- Ubuntu下启动Apache对.htaccess 的支持
- 基于maven的自动部署(适用于tomcat7和tomcat8)
- nginx的五种负载算法模式
- CentOS 7下安装MySQL后重置root密码方法
- OpenCV文档阅读笔记 —— Introduction节
- Storm运维-增加槽位
- 分享一个popupwindow工具类
- 每日Linux -useradd,userdel
- Linux CentOS6.5下编译安装MySQL 5.6.15
- Linux下安装maven
- Keepalived MySQL master-master配置高可用
- 制作initrd(4):initrd.img中启动脚本init分析