HDU 4405 Aeroplane chess (expected dp)

Question: On a flying chess map, you just start at 0 o’clock and end at n o’clock. You can roll a dice each time and advance 1~6 steps with equal probability. When you reach or exceed point n, you win . There are m channels in the figure, that is, when you are at x[i], you will lead to y[i] for free. Now let you calculate: how many times do you expect to roll the dice if you want to win?

Idea: Let f[i] be the point i, and we need to roll f[i] times. Just transfer directly from the last 6 steps. Note that when there is a free channel, it is definitely better to take the free channel, so we can transfer directly from the place where the channel ends to the place where the channel starts.

Code:

#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;
}

Guess you like

Origin blog.csdn.net/Joker_He/article/details/111232819