http://www.jiuzhang.com/article/Google%202016%E5%B9%B412%E6%9C%88%20SDE%20Onsite%E9%9D%A2%E7%BB%8F/
http://www.cnblogs.com/AndyJee/p/4846566.html
(1)初阶:有一个100层高的大厦,你手中有两个相同的玻璃围棋子。从这个大厦的某一层及更高的层扔下围棋子就会碎,用你手中的这两个玻璃围棋子,找出一个最优的策略(扔最少的次数),来得知那个临界层面。
(2)进阶:如果大厦高度是N层,你有K个棋子,请问最少需要扔几次可以知道得临界层?
package com.graph;
import java.util.*;
import javax.security.auth.kerberos.KerberosKey;
import java.util.*;
/**
* Your Trie object will be instantiated and called as such: Trie trie = new
* Trie(); trie.insert("lintcode"); trie.search("lint"); will return false
* trie.startsWith("lint"); will return true
*/
public class Solution {
public static void main(String[] args) {
Solution s = new Solution();
// s.maximalRectangle(new boolean[][]
// {{true,true,false,false,true},{false,true,false,false,true},{false,false,true,true,true},{false,false,true,true,true},{false,false,false,false,true}});
// s.maximalRectangle(new boolean[][] {{true}});
// s.pick(new int[] {10,4,5,12});
// s.shortestPalindrome("aacecaaa");
int res = s.drop(100);
System.out.println("");
}
//N層,2個棋子
//數學特性
public int drop(int n) {
// x*x+x-2n>=0
int a = 1;
int b = 1;
int c = -2 * n;
double[] res = equation(a, b, c);
return (int) Math.ceil(res[0]);
}
double[] equation(int a, int b, int c) {
double delta = b * b - 4 * a * c;
double[] res;
if (delta < 0) {
return new double[0];
} else if (delta > 0) {
res = new double[2];
double tmp1,tmp2;
tmp1 = ((-b + Math.sqrt(delta)) / (2 * a));
tmp2 = ((-b - Math.sqrt(delta)) / (2 * a));
res[0] = Math.max(tmp1, tmp2);
res[1] = Math.max(tmp1, tmp2);
} else {
res = new double[] {-b / (2 * a)};
}
return res;
}
//N層,k個棋子
//動態規劃
public int drop_dp(int n, int k) {
int[][] dp = new int[n][k];
//边界
for(int i=1; i<=n; i++) {
dp[i][1] = i;
}
for(int j=1; j<=k; j++) {
dp[1][j] = 1;
}
for(int i=2; i<=n; i++) {
for(int j=2; j<=k; j++) {
for(int t=1; t<i; t++) {
dp[i][j] = Math.min(dp[i][j], Math.max(dp[t-1][j-1], dp[i-t][j])+1);
}
}
}
return dp[n][k];
}
}