力扣(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] = \begin{cases} 0.5&\text{if }i\le 0,j\le0\\ 1.0&\text{if }i\le 0,j>0\\ 0.0&\text{if }i> 0,j\le0\\ (f[i-4][j]+f[i-3][j-1]+f[i-2][j-2]+f[i-1][j-3])\div4 &\text{if }i> 0,j>0 \end{cases} 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. 时间复杂度 : 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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清墨韵染

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值