Leetcode 375 - Guess Number Higher or Lower II(区间dp)

本文介绍了一种猜数字游戏的算法,目标是在1到n的范围内找出任意一个选定的数字,同时使得总猜测成本最小化。通过动态规划的方法定义状态d[i][j]为猜出区间[i,j]内任意数字所需的最小代价,并给出了解决方案的时间和空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

猜数字游戏,给定一个n,假设我从1到n里面选择了一个数作为我的target,如果我这次猜的x并且猜错了, 那么需要付出代价x,能够猜出1到n里面任意一个数的最小代价。

思路

这道题和之前的Guess Number Higher or Lower的不同之处在于:之前一道题是规定了每次猜中间一个数,因此值二分即可。这道题是每次可以从[L, R]里面猜任意一个数,但是要求总的代价最小。

状态表示d[i][j],猜出区间[i, j]里面任意一个数需要的最小代价。

现在,我们可以这样考虑,当我们要猜的数在[i, j]中时,我们需要做的就是从[i, j]里面猜一个数,假设猜的是k。

  1. 如果target更大,那么我们就需要在[k + 1, j]里面猜,并且付出代价k。
  2. 如果target更小,那么我们就需要在[i, k - 1]里面猜,并且付出代价k。
  3. 如果targt == k,那么我们只需要付出代价k。

因为要确保我们总能赢,因此可以得到我们的转移方程
d[i][j]=min{max(d[i][k1],d[k+1][j])+k|ikj}

时间复杂度O(n3)
空间复杂度O(n2)

代码

const int maxn = 1005;
int d[maxn][maxn];

class Solution {
public:
    int dfs(int i, int j) {
        if (d[i][j] != -1) return d[i][j];
        if (i >= j) return d[i][j] = 0;
        if (j == i + 1) return d[i][j] = i;
        d[i][j] = 0x3e3e3e3e;
        for (int k = i; k <= j; k++) {
            d[i][j] = min(d[i][j], max(dfs(i, k - 1), dfs(k + 1, j)) + k);
        }
        return d[i][j];
    }

    int getMoneyAmount(int n) {
        memset(d, -1, sizeof(d));
        return dfs(1, n);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值