leetcode-猜数字大小2

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

我从 1n 之间选择一个数字,你来猜我选了哪个数字。

每次你猜错了,我都会告诉你,我选的数字比你的大了或者小了。

然而,当你猜了数字 x 并且猜错了的时候,你需要支付金额为 x 的现金。直到你猜到我选的数字,你才算赢得了这个游戏。

示例:

1
2
3
4
5
6
7
8
9
n = 10, 我选择了8.

第一轮: 你猜我选择的数字是5,我会告诉你,我的数字更大一些,然后你需要支付5块。
第二轮: 你猜是7,我告诉你,我的数字更大一些,你支付7块。
第三轮: 你猜是9,我告诉你,我的数字更小一些,你支付9块。

游戏结束。8 就是我选的数字。

你最终要支付 5 + 7 + 9 = 21 块钱。

给定一个 n ≥ 1,计算你至少需要拥有多少现金才能确保你能赢得这个游戏。

思路

记录a(i,j)表示从i到j的结果,那么有如下公式:

a(i,j)=min{ x+max{a(i,x-1),a(x+1,j)}} 其中x从i到j;

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Solution {
public int getMoneyAmount(int n) {
//a(i,j)=min{ x+max{a(i,x-1),a(x+1,j)}}

int [][]a = new int[n+1][n+1];
for(int j =1;j<=n;j++){
for(int i =j;i>=1;i--){
if(i==j){
a[i][j]=0;
}else if(j-i==1){
a[i][j]=i;
}else{
int min=i+a[i+1][j];
for(int x=i+1;x<=j;x++){
int left = 0;
if(x-1>i){
left=a[i][x-1];
}
int right= 0;
if(x+1<j){
right=a[x+1][j];
}
int temp = x+(left>right?left:right);
min = temp>min?min:temp;
}
a[i][j]=min;
}
}
}
return a[1][n];
}
}