• 375. 猜数字大小 II 力扣(中等) 区间动态规划、记忆化搜索


    375. 猜数字大小 II

    我们正在玩一个猜数游戏,游戏规则如下:

    我从 1 到 n 之间选择一个数字。
    你来猜我选了哪个数字。
    如果你猜到正确的数字,就会 赢得游戏 。
    如果你猜错了,那么我会告诉你,我选的数字比你的 更大或者更小 ,并且你需要继续猜数。
    每当你猜了数字 x 并且猜错了的时候,你需要支付金额为 x 的现金。如果你花光了钱,就会 输掉游戏 。
    给你一个特定的数字 n ,返回能够 确保你获胜 的最小现金数,不管我选择那个数字 。

    示例 1:

    输入:n = 10
    输出:16


    学习要点:

    记忆化搜索:dp[l][r]在循环的时候是不赋值的,一定是得到最优解之后,才赋值为dp[l][r],然后给别的子问题用。自己还不是最优,怎么让别人也最优。

    区间动态规划:

    题解:

    代码:记忆化搜索

    class Solution {
    public:
        int dp[205][205];
        int dfs(int l,int r)
        {
            if (l>=r) return 0;
            if (dp[l][r]>0) return dp[l][r];
            int sum=0x7fffffff;
            for(int i=l;i<=r;i++)
                sum=min(sum,max(dfs(l,i-1),dfs(i+1,r))+i);
            
            dp[l][r]=sum;   // 是得到最优值sum才能赋值的,不能在中间得到解。
            return dp[l][r];
        }
        int getMoneyAmount(int n) {
         memset(dp,0,sizeof(dp));
         return dfs(1,n);
        }
    };

     改写成区间DP:

    class Solution {
    public:
        int dp[205][205];
        int getMoneyAmount(int n) {
      
        // 改写成:区间dp
         for(int len=1;len<=n;len++)   // dp[i][j]:起始点i,终点为j的区间
          for(int i=1;i+len-1<=n;i++)
          {
              int j=i+len-1;
              if(len==1) {dp[i][j]=0; continue;}
              dp[i][j]=0x7fffffff;
              for(int k=i;k<=j;k++)
                  dp[i][j]=min(dp[i][j],max(dp[i][k-1],dp[k+1][j])+k);
          }
          return dp[1][n];
        }
    };
  • 相关阅读:
    linux查看系统类型和版本
    javascript 中的继承实现, call,apply,prototype,构造函数
    redis原理分析
    HashTable 简述
    算法之 快速排序
    react js 之生命周期
    Java源代码编译过程
    Java字节码文件结构---概述
    Java程序运行时内存划分
    数据结构--汉诺塔--借助栈实现非递归---Java
  • 原文地址:https://www.cnblogs.com/stepping/p/15546189.html
Copyright © 2020-2023  润新知