分汤

一、题目描述

题目链接:https://leetcode-cn.com/problems/soup-servings/

 

二、题目分析

参考题解:https://leetcode-cn.com/problems/soup-servings/solution/leetcode-fen-tang-dong-tai-gui-hua-ji-yi-sou-suo-b/

还有评论:https://leetcode-cn.com/problems/soup-servings/comments/

题目把我看得一愣一愣的,看好久都不知道要干嘛。就是说我们每次提供N份A汤,N份B汤,然后把汤倒掉(我觉得这样说比较好理解),然后有四个倒的策略:

1、A倒100份,B不倒

2,A倒75份,B倒25份

3,A倒50份,B倒50份

4、A倒25份,B倒75份

这里我们可以使用一个二维数组dp[i][j]来表示当有i份A汤和j份B汤倒掉后得出的概率。当我们计算dp[i][j]的时候,用dp[i - 100][j]来表示A汤倒掉100份对应的概率,dp[i - 75][j - 25]来表示A汤倒掉75份,B汤倒掉25份对应的概率,dp[i-50][j-50],dp[i-25][j-75]同理,然后把四个概率加起来*0.25,就是dp[i][j]。因此我们是一个从前往后的dp。

 

三、代码

    public double soupServings(int N) {
      // 这里看题解说是经过数学验证的,那就,这样吧
      if(N>=4800)return 1;
      // 这里是一个trick,因为按照题目,倒掉的汤基数是25,因此我们可以缩小N的范围
      // 余数如果不为0我们也当成1份算
      N=N/25+((N%25==0)?0:1);
      double dp[][]=new double[N+1][N+1];
      // 当A汤为0时,A汤一定先倒完
      Arrays.fill(dp[0],1);
      // 除非B汤也为0
      dp[0][0]=0.5;
      for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            dp[i][j]=0.25*(dp[Math.max(0,i-4)][j]+dp[Math.max(0,i-3)][Math.max(0,j-1)]+dp[Math.max(0,i-2)][Math.max(0,j-2)]+dp[Math.max(0,i-1)][Math.max(0,j-3)]);  
        }
      }
      return dp[N][N];
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值