zoukankan      html  css  js  c++  java
  • (算法)宝石升级问题

    题目:

    有一块宝石,1级升2级成功率100%,2级升3级成功率80%,3级升4级成功率60%,4级升5级成功率40%,每次升级失败时降回到1级。请问一块1级宝石升到5级平均要多少次? 

    思路:

    问题:求一块1级宝石升级到5级的期望次数

    1、蒙特卡洛模拟试验

    考虑一下期望的定义,所有的可能的次数*出现该次数的概率之和。出现的次数可能为无穷大,但当次数达到一定数量时,期望就收敛了,因此可以通过概率的模拟试验来实现。

    2、有限状态机的概率转移思想

    假设dp(i,j)为1级升到5级的平均次数,则有以下递推式:

    dp(1,5) = 1.0 * dp(2,5) + 0.0 * dp(1,5)+1

    dp(2,5) = 0.8 * dp(3,5) + 0.2 * dp(1,5)+1

    dp(3,5) = 0.6 * dp(4,5)+ 0.4 * dp(1,5)+1

    dp(4,5) = 0.4 * dp(5,5) + 0.6 * dp(1,5)+1

    其中dp(5,5)=0;

    求解上述方程组,得到dp(1,5)即为答案,答案为17.0833.

    代码:

    1、蒙特卡洛模拟试验

    #include <iostream>
    #include <time.h>
    #include <stdlib.h>
    #include <iomanip>
    
    using namespace std;
    
    bool isUpgrade(double p){
        double prob=rand()/(double)(RAND_MAX);
        if(prob<=p)
            return true;
        else
            return false;
    }
    
    double ExpectedUpgradeTimes(double *P,int n){
        const int TIMES=100000000;
        int grade=0;
        int times=0;
        int total=0;
        double expect=0;
    
        for(int i=0;i<TIMES;i++){
            grade=0;
            times=0;
            while(grade!=n-1){
                if(isUpgrade(P[grade]))
                    grade++;
                else
                    grade=0;
                times++;
            }
            total+=times;
        }
        expect=(double)total/TIMES;
        return expect;
    }
    
    int main(){
        srand((unsigned int)time(NULL));
        double P[]={1.0,0.8,0.6,0.4};
        int len=sizeof(P)/sizeof(P[0]);
    
        double exp=ExpectedUpgradeTimes(P,len+1);
    
        cout<<fixed<<exp<<endl;
        cout << setprecision(2) << exp << endl;
        return 0;
    }

    2、动态规划

    #include <iostream>
    #include <time.h>
    #include <stdlib.h>
    #include <iomanip>
    
    using namespace std;
    
    double ExpectedUpgradeTimes_DP(double *P,int n){
        double A[n],B[n];
        double p[n];
        p[1] = 1.0;p[2] = 0.8;p[3]=0.6;p[4] =0.4;
        for(int i=4;i>=1;i--){
            A[i] = 1+A[i+1]*p[i];
            B[i] = p[i]*B[i+1]+1-p[i];
            cout<<A[i]<<" "<<B[i]<<endl;
        }
        double t = A[1]/(1-B[1]);
    
        return t;
    }
    
    int main(){
        srand((unsigned int)time(NULL));
        double P[]={1.0,0.8,0.6,0.4};
        int len=sizeof(P)/sizeof(P[0]);
    
        double exp=ExpectedUpgradeTimes_DP(P,len+1);
    
        cout<<fixed<<exp<<endl;
        cout << setprecision(2) << exp << endl;
        return 0;
    }
  • 相关阅读:
    socket的几大异常以及其出现的原因
    将文件打包成apk
    putty失活不挂起运行
    天气免费接口
    内存泄漏
    The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build
    009 预处理 #pragma once; typedef; #ifdef
    008 区别 : NULL nullptr
    007 头文件 : 作用/组织/包含
    006 整数/浮点数/cpu频率
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4755388.html
Copyright © 2011-2022 走看看