Google算法题:扔鸡蛋/扔棋子

这篇博客探讨了Google面试中的一道经典算法题——扔鸡蛋问题。问题分为两个阶段:(1)在100层大厦中,用两个相同玻璃棋子找出摔碎的临界层,目标是最少次数;(2)大厦高度为N层,拥有K个棋子,寻求确定临界层所需的最少扔棋子次数。文章提供了问题解析和可能的最优策略。
摘要由CSDN通过智能技术生成


http://www.jiuzhang.com/article/%E4%B9%9D%E7%AB%A0%E7%AE%97%E6%B3%95%E7%B2%BE%E9%80%89%E9%9D%A2%E8%AF%95%E9%A2%9822%20%E6%89%94%E6%A3%8B%E5%AD%90/

http://www.jiuzhang.com/article/Google%202016%E5%B9%B412%E6%9C%88%20SDE%20Onsite%E9%9D%A2%E7%BB%8F/


https://mp.weixin.qq.com/s?__biz=MzA5MzE4MjgyMw==&mid=10002007&idx=2&sn=4d1d93827e5f682f55ef672ad2a2f724&mpshare=1&scene=1&srcid=0317HcQIbmjzYlt8VKN7yYsD&key=5657e61c2ec7753d95bfa5b1b266b22e73177db4e28d1d194744956381d518faebc29142fc75796ec17f2f128dc2378bd8117f126a1d0a2509e1ec1d31595320398fc36877ec821652ece1d84db7c92a&ascene=0&uin=MTUyMzg3NjAwMA%3D%3D&devicetype=iMac+MacBookAir7%2C1+OSX+OSX+10.12.3+build(16D32)&version=12020010&nettype=WIFI&fontScale=100&pass_ticket=0AiIToHJN8yqpuqRAsA5PaaQMJr8KtvlnZ2EqkX0zx%2BEZweRvHKyF%2ByjmycpUbVn

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];
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值