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

来源:互联网 发布:linux lcd驱动程序 编辑:程序博客网 时间:2024/05/16 10:09

题意

猜数字游戏,给定一个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);    }};
0 0
原创粉丝点击