Google-HK-2012-interview-"pizza"(1)
来源:互联网 发布:非法网络彩票赌博 编辑:程序博客网 时间:2024/06/06 21:04
汉堡吐了吐烟圈说:提起女神就闹心,女神都不理我。
我说为什么不换个别的。他说,喜欢,没办法。
他问我,你就没有喜欢得非她不可的么。
我说没有。也许曾经有。
早上和Parker大神讨论了一个新的idea,大概是想要做类似OJ的网站,Parker说太难,而且test case的validate工作量十分大,建议我找到工作之后有空去写这样的web。然后他提到他在面HK Google的一道题目,叫我解。我没有想出来,最后照着他得思路我做了一下。
=====================================================
#1 题目是这样的:(好吧,描述是我自己脑补的,毕竟万圣节一个人写代码,呵呵)
万圣节,你一个人在寝室写代码,突然饿了,冰箱没有吃的东西了,于是你订了一份pizza。开门的时候看到送外卖的小哥cosplay成Fin the Human(好吧,我承认我喜欢Adventure time),他看到我一脸寂寞就知道是程序员,说,小费少收一点。好吧,你赢了。
我准备吃pizza了,这时候两个寂寞的损友也过来我家了,说要蹭饭。好,现在问题来了:
pizza被切成了3 * n片,每一片pizza有大有小,假设大小用pizza[i]表示。每次我选择一片pizza[i]吃,两个损友就会吃pizza[i-1]和pizza[i+1],注意这是环,自动脑补。
那么我怎么可以保证我所吃到的pizza总和最大呢?
=====================================================
于是我想写个程序来解决这个问题。
孤独的我继续写代码,听着好久没有听过的豆瓣FM,不知道为什么douban的随机开始又符合自己口味了,开始尝试新花样了。估计machine learning又用了新的算法,或者库更加完善了。
"why did the blues go on singing."
原来邓紫棋唱的《后会无期》的主题曲是翻唱1997年的Julie London唱的<The end of the world>。
扯远了,实在太悲伤。赶紧回来。
=====================================================
#2 算法:
考虑这个ring,Greedy算法行不通,比方说{1, 1, 1, 9, 10, 9}。考虑使用dp,当时Parker说使用一个3n-bit的flag去表明吃pizza的状态,那么这个dp的复杂度是O(2^n)。所以要选择更好的dp的状态。
好,我们换个思路。假设我们已知:dp[i][j]表示从第i块pizza到第j块pizza之间,自己能得到的最大值。注意,这里pizza(i)和pizza(j)不允许连成一个ring,只能是line。
那么之前的pizza问题就可以转换为线性问题:假设最后取的3块pizza分别是x, y, z。那么这3块pizza所分割成为的line就是之前dp[i][j]所表示的问题。
自己可以吃的pizza的最大值就是(假设x < y < z):
max{x, y, z} + dp[x+1][y-1] + dp[y+1][z-1] + dp[z+1][x-1+n]
最后这里从z+1回到x-1有个突变点,在处理数据的时候只要copy一份pizza的数据到原始的pizza的末端就可以了。
只要枚举所有的x,y,z组合情况(O(n^3)复杂度),计算好dp,然后取n^3情况中的最大值就可以了。
于是问题变成如何求解dp[i][j]。其中必须满足(j - i + 1) % 3 == 0。否则无法取到最后3块pizza(每次吃的时候都是连续3块pizza被吃掉的)。
计算dp[i][j]的时候,有两种情况:
#1 pizza[i]和pizza[j]是在最后一次被其他两个朋友同时吃掉的。只需要枚举自己吃的最后一块k。
dp[i][j] = k + dp[i+1][k-1] + dp[k+1][j-1]。要求[(k-1)-(i+1)+1]%3==0,剩下另外一边当然也是3得倍数(因为i,j有限制)。
#2 pizza[i]和pizza[j]分别在两次被其他两个朋友吃掉的。那么枚举分割点k。
dp[i][j] = dp[i][k] + dp[k+1][j]。要求(k-i+1)%3==0。
=====================================================
#3 数据结构:
dp[i][j]就足够了。
=====================================================
#4 代码:
大神们请轻拍,因为实在苦于没有test case,只能瞎猜了。。。
这里的代码是有误的,请看(2),我自己写了一些test case并且修改了一下代码。
public class Solution {// solve the problempublic static int maxPizzaValue(int[] pizza) {int n = pizza.length;int maxPizza = 0;// copy pizza to pizzaint[] bigPizza = new int[2*n];System.arraycopy(pizza, 0, bigPizza, 0, n);System.arraycopy(pizza, 0, bigPizza, n, n);int[][] dp = calDP(n, bigPizza);for (int x = 0; x < n-2; x++) {for (int y = x+1; y < n-1; y++) {for (int z = y+1; z < n; z++) {// check the valid divisionif ((y - x - 1) % 3 == 0 && (z - y - 1) % 3 == 0) {int val = max(x, y, z) + dp[x+1][y-1] + dp[y+1][z-1] + dp[z+1][x-1+n];if (val > maxPizza) maxPizza = val;}}}}return maxPizza;}// calculate dp elements// dp[i][j] means max value from index i to jpublic static int[][] calDP (int n, int[] A) {int[][] dp = new int[2*n][2*n]; // initfor (int i = 0; i < 2*n; i++) {for (int j = 0; j < 2*n; j++) {dp[i][j] = 0;}}// base casefor (int i = 0; i <= 2*n-3; i++) {dp[i][i+2] = max(A[i], A[i+1], A[i+2]); // base case}int len = 6;while (len <= n) {for (int i = 0; i <= 2*n-len; i++) {int j = i+len-1;// must take the i, j at the same roundfor (int k = i+1; k < j; k += 3) {int val = A[k];val += k-1 < i+1 ? 0 : dp[i+1][k-1];val += j-1 < k+1 ? 0 : dp[k+1][j-1];dp[i][j] = dp[i][j] > val ? dp[i][j] : val;}// take the i, j at different roundfor (int k = i; k <= j; k++) {if ((k - i + 1) % 3 == 0) {int val = dp[i][k] + dp[k+1][j];dp[i][j] = dp[i][j] > val ? dp[i][j] : val;}}}len += 3;}return dp;}// return the max of the 3public static int max(int x, int y, int z) {int max = x > y ? x : y;max = max > z ? max : z;return max;}}
- Google-HK-2012-interview-"pizza"(1)
- Google-HK-2012-interview-"pizza"(2)
- 访问google.com而不是google.hk
- 如何修复google自动跳转google.hk?
- google搜索避免跳转到google hk
- PIZZA
- Ten Google interview questions
- Google Interview Preparation
- Google.com.hk-关闭搜索过滤
- Google.com.hk时常进不了
- Google 只是去了HK而已。。。。
- 修改google搜索引擎非hk方法
- http://www.google.com.hk/patents/US8566217
- 近期google.com.hk无法访问的解决方法
- 强制Google.com.hk域名使用https
- 【面试总结】Google Interview Phone Interview
- Use google.com instead of google.com.hk
- google.cn(g.cn) redirect to google.com.hk
- iOS内存错误EXC_BAD_ACCESS的解决方法
- 【C99标准翻译1】sizeof
- 获取句柄
- LeetCode 133 Remove Nth Node From End of List
- linux下目录详解
- Google-HK-2012-interview-"pizza"(1)
- 无线传感器网络路由协议AODV(Ad hoc on-demand distance vector routing)
- 十八届三中全会关于全面深化改革若干重大问题的决定
- Digital Ocean使用SSH Key登录
- 如何隐藏控制台窗口
- 并发问题:大数据量的访问
- Eclipse如何关联源码以及v4包关联源码
- kvm虚拟机在线迁移
- gedit默认编码设置