【C++】17行最优解
丢棋子问题
http://www.nowcoder.com/questionTerminal/d1418aaa147a4cb394c3c3efc4302266
核心思路:每次扔的位置都是最佳的,i个棋子扔time次,第1次时,如果碎了,向下可以探测“i-1个棋子扔time-1次”层;如果没碎,向上可以探测“i个棋子扔time-1次”层。上下层数加当前1层即为i个棋子扔time次能探测的最大层数
class Solution { public: int solve(int n, int k) { if(n <= 1 || k == 1) return n; //层数小于等于1和棋子数等于1的情况 int best = log2(n) + 1; //棋子足够条件下扔的最小次数 if(k >= best) return best; //如果棋子数足够则返回最小次数 int dp[k + 1]; //用来记录扔1~k个棋子能探测的最大层数 for(int &i: dp) i = 1; //无论有几个棋子扔1次都只能探测一层 for(int time = 2;;time++) { //从扔第2次开始(前面初始化dp数组时扔了第1次) for(int i = k; i >= 2; i--) { //从k个棋子开始刷新dp数组(倒过来刷新省去记录临时值的步骤) dp[i] = dp[i] + dp[i-1] + 1; //关键一步 if(dp[i] >= n) return time; //如果探测层数大于n,则返回扔的次数 } dp[1] = time; //1个棋子扔time次最多探测time层 } } };