• 力扣(LeetCode)808. 分汤(C++)


    动态规划

    在这里插入图片描述

    如图,本题的状态表示,是二维 d p dp dp f [ i , j ] f[i,j] f[i,j] i i i 表示剩余的 a a a j j j 表示剩余的 b b b f [ i , j ] f[i,j] f[i,j] 表示 a a a 先取完的概率 。

    按照 i / j i/j i/j 的剩余数量做集合划分
    ①当 i ≤ 0 , j ≤ 0 i\le 0,j\le0 i0,j0 a / b a/b a/b 同时取完 , 线性概率 f [ i ] [ j ] = 1.0 ÷ 2 = 0.5 f[i][j]=1.0\div2=0.5 f[i][j]=1.0÷2=0.5
    ②当 i ≤ 0 , j > 0 i\le 0,j>0 i0,j>0 a a a 先取完 , f [ i ] [ j ] = 1.0 f[i][j]=1.0 f[i][j]=1.0
    ③当 i > 0 , j ≤ 0 i> 0,j\le0 i>0,j0 b b b 先取完 , f [ i ] [ j ] = 0.0 f[i][j]=0.0 f[i][j]=0.0
    ④当 i > 0 , j > 0 i> 0,j>0 i>0,j>0 a / b a/b a/b 都有剩余 , 有均等概率进行 4 4 4 种取法 , 为了便于操作 , 将所有取法的取值 ÷ 25 \div 25 ÷25 , 那么初始汤量 n = n ÷ 25 n = n\div25 n=n÷25 f [ i ] [ j ] = ( f [ i − 4 ] [ j ] + f [ i − 3 ] [ j − 1 ] + f [ i − 2 ] [ j − 2 ] + f [ i − 1 ] [ j − 3 ] ) / 4 f[i][j]= (f[i-4][j]+f[i-3][j-1]+f[i-2][j-2]+f[i-1][j-3])/4 f[i][j]=(f[i4][j]+f[i3][j1]+f[i2][j2]+f[i1][j3])/4

    状态转移方程
    f [ i ] [ j ] = { 0.5 if  i ≤ 0 , j ≤ 0 1.0 if  i ≤ 0 , j > 0 0.0 if  i > 0 , j ≤ 0 ( f [ i − 4 ] [ j ] + f [ i − 3 ] [ j − 1 ] + f [ i − 2 ] [ j − 2 ] + f [ i − 1 ] [ j − 3 ] ) ÷ 4 if  i > 0 , j > 0 f[i][j] = {0.5if i0,j01.0if i0,j>00.0if i>0,j0(f[i4][j]+f[i3][j1]+f[i2][j2]+f[i1][j3])÷4if i>0,j>0 f[i][j]=0.51.00.0(f[i4][j]+f[i3][j1]+f[i2][j2]+f[i1][j3])÷4if i0,j0if i0,j>0if i>0,j0if i>0,j>0

    数学期望 : 取 a = ( 4 + 3 + 2 + 1 ) ÷ 4 = 2.5 a=(4+3+2+1)\div4=2.5 a=(4+3+2+1)÷4=2.5 b = ( 3 + 2 + 1 + 0 ) ÷ 4 = 1.5 b=(3+2+1+0)\div 4=1.5 b=(3+2+1+0)÷4=1.5 ,数学期望 a > b a>b a>b ,当 n n n 很大时 , a a a 先取完的概率趋于 1 1 1 。经测试 , n ÷ 25 ≥ 189 n\div 25 \ge 189 n÷25189 时 , a a a 先取完的概率近似为 1 1 1

    朴素dp
    class Solution {
    public:
        int g(int x){//分汤后小于0,归为0
            return max(0,x);
        }
        double soupServings(int n) {
            // n = (n+24)/25;//向上取整
            n = n / 25 + (n%25!=0);
            if(n>=189) return 1;
            vector<vector<double>> f(n+1,vector<double>(n+1));
            for(int i = 0;i<=n;i++)
                for(int j = 0;j<=n;j++){
                    if(!i&&!j) f[i][j] = 0.5;
                    else if(!i&&j) f[i][j] = 1.0;
                    else if (i&&!j) f[i][j] = 0.0;
                    else{//(i&&j)
                        f[i][j] = (f[g(i-4)][j]+f[g(i-3)][g(j-1)]+f[g(i-2)][g(j-2)]+f[g(i-1)][g(j-3)])/4;
                    }
                }
            return f[n][n];
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    1. 时间复杂度 : O ( n 2 ) O(n^2) O(n2) , 状态转移的时间复杂度 O ( n 2 ) O(n^2) O(n2)
    2. 空间复杂度 : O ( n 2 ) O(n^2) O(n2) f f f 数组的空间复杂度 O ( n 2 ) O(n^2) O(n2)
    AC

    AC

  • 相关阅读:
    产品帮助中心必备的6大常规功能,你知道几个?
    css3 函数汇总(笔记)
    NAT模式LVS负载均衡群集部署
    在 React 项目中全量使用 Hooks
    Revit插件“有求必应”的【批量喷头】生成喷头
    在pandas中使用query替代loc进行高效简洁的条件筛选
    SSM项目整合Redis
    餐厅订座预约小程序的效果如何
    域名竞价要注意什么?
    普冉PY32系列(八) GPIO模拟和硬件SPI方式驱动无线收发芯片XN297LBW
  • 原文地址:https://blog.csdn.net/Innocence02/article/details/127958296