Description
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
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
飞行棋盘长度为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;
}