HDU 4405 Aeroplane chess(期望dp)

题意: 在一张飞行棋地图上,你刚开始在0点,终点是n点,你每次可以摇一个骰子,等概率前进1~6步,当你走到或者超过点n,即胜利。图中有m条通道,即当你在x[i]时,免费通向y[i]点。现在让你计算:你要获得胜利,期望摇骰子的次数是多少?

思路: 设f[i]为走到i点,还需要摇f[i]次骰子。直接从后6步分别转移就行了。注意有免费通道的时候,走免费通道肯定是更好的,那么我们直接从通道结束的地方向通道开始的地方转移就行。

代码:

#include<bits/stdc++.h>
#include<cstring>
#define endl '\n'
#define null NULL
#define ls p<<1
#define rs p<<1|1
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ll long long
#define int long long
#define lowbit(x) x&-x
#define pii pair<int,int>
#define ull unsigned long long
#define pdd pair<double,double>
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read()
{
    
    
    int x=0,f=1;
    char ch=gc();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')
            f=-1;
        ch=gc();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=gc();
    }
    return x*f;
}
using namespace std;
const int N=1e5+666;
const int inf=0x3f3f3f3f;
const int mod=998244353;
const double eps=1e-7;
const double PI=acos(-1);

int b[N];
double f[N];
int solve()
{
    
    
    int n,m;
    double p = 1.0/6.0;
    while(cin>>n>>m)
    {
    
    
        if(n==0&&m==0)
            break;
        memset(b,-1,sizeof b);
        for(int i=1; i<=m; i++)
        {
    
    
            int x,y;
            cin>>x>>y;
            b[x]=y;
        }
        memset(f,0,sizeof f);
        for(int i=n-1; i>=0; i--)
        {
    
    
            if(b[i]!=-1)
            {
    
    
                f[i]=f[b[i]];
            }
            else
            {
    
    
                f[i]=0.0;
                for(int j=i+1; j<=i+6; j++)
                {
    
    
                    f[i] += p*f[j];
                }
                f[i]+=1.0;
            }
        }
        printf("%.4f\n",f[0]);
    }
}

signed main()
{
    
    
//    int _;
//    cin>>_;
//    while(_--)
    solve();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Joker_He/article/details/111232819