作者简介:硕风和炜,CSDN-Java领域新星创作者,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享
座右铭:人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?
375. 猜数字大小 II
我们正在玩一个猜数游戏,游戏规则如下:
我从 1 到 n 之间选择一个数字。
你来猜我选了哪个数字。
如果你猜到正确的数字,就会赢得游戏 。
如果你猜错了,那么我会告诉你,我选的数字比你的更大或者更小 ,并且你需要继续猜数。
每当你猜了数字 x 并且猜错了的时候,你需要支付金额为 x 的现金。如果你花光了钱,就会输掉游戏 。
给你一个特定的数字 n ,返回能够确保你获胜的最小现金数,不管我选择那个数字 。
输入:n = 10
输出:16
解释:制胜策略如下:
示例 2:
输入:n = 1
输出:0
解释:只有一个可能的数字,所以你可以直接猜 1 并赢得游戏,无需支付任何费用。
示例 3:
输入:n = 2
输出:1
解释:有两个可能的数字 1 和 2 。
提示:
1 <= n <= 200
注意,代码的实现方式可以有很多,大家根据自己的习惯来就好
class Solution {
public int getMoneyAmount(int n) {
return process(1,n);
}
public int process(int left,int right){
if(left>=right) return 0;
int min=Integer.MAX_VALUE;
for(int x=left;x<=right;x++){
int pay=Math.max(process(left,x-1),process(x+1,right))+x;
min=Math.min(min,pay);
}
return min;
}
}
大家不要看到时间超限就害怕,相反,看到这个我们更应该放心,这是我们期待的结果。
class Solution {
public int getMoneyAmount(int n) {
int[][] dp=new int[n+5][n+5];
for(int i=0;i<=n;i++) Arrays.fill(dp[i],-1);
return process(1,n,dp);
}
public int process(int left,int right,int[][] dp){
if(dp[left][right]!=-1) return dp[left][right];
if(left>=right) return dp[left][right]=0;
int min=Integer.MAX_VALUE;
for(int x=left;x<=right;x++){
int pay=Math.max(process(left,x-1,dp),process(x+1,right,dp))+x;
min=Math.min(min,pay);
}
return dp[left][right]=min;
}
}
加个缓存表就是香,通过!
继续改进!
class Solution {
public int getMoneyAmount(int n) {
int[][] dp=new int[n+5][n+5];
for(int i=n;i>0;i--){
for(int j=i+1;j<=n;j++){
dp[i][j]=Integer.MAX_VALUE;
for(int x=i;x<=j;x++){
dp[i][j]=Math.min(Math.max(dp[x+1][j],dp[i][x-1])+x,dp[i][j]);
}
}
}
return dp[1][n];
}
}
最后,我想送给大家一句一直激励我的座右铭,希望可以与大家共勉!