CareerCup A Ctrl+A Ctrl+C Ctrl+V

265 篇文章 1 订阅
231 篇文章 0 订阅
1. A 
2. Ctrl+A 
3. Ctrl+C 
4. Ctrl+V 

If you can only press the keyboard for N times (with the above four keys), please write a program to produce maximum numbers of A. If possible, please also print out the sequence of keys. 

So the input parameter is N (No. of keys that you can press), the output is M (No. of As that you can produce).


-------------------------------------------------------------

We define dp[i] as the output give the input parameter i

Using Ctrl A + Ctrl C + Ctrl V + Ctrl V...the result is 

dp[i] = max(dp[i-3]*1, dp[i-4]*2, ...dp[i-9]*7, dp[i-10]*8,.... )

Take Notice that Ctrl A + Ctrl C + Ctrl V won't double the sequence because the cursor doesn't move 大哭

While Using Ctrl A + Ctrl C + Ctrl V + Ctrl V + Ctrl A + Ctrl C + Ctrl V + Ctrl V ...

dp[i] = max(dp[i-4]*2, dp[i-8]*4, dp[i-12]*8, dp[i-16]*16...)

While Using Ctrl A + Ctrl C + Ctrl V + Ctrl V + Ctrl V + Ctrl A + Ctrl C + Ctrl V + Ctrl V  + Ctrl V...

dp[i] = max(dp[i-5]*3, dp[i-10]*9, dp[i-15]*9...)

........

........

Pay attention to dp[i] = dp[i-9]*7 or dp[i-4]*2 && dp[i-5]*3, however, 7 > 2 * 3

But for dp[i] = dp[i-10]*8 or dp[i-5]*3 && dp[i-5]*3, 3*3 > 8

and dp[i] = dp[i-11]*9 or dp[i-5]*3 && dp[i-6]*4, 3*4 > 9


Divide a number num into x and y, (x - 2) * (y -2) arrives the maximum when x tends to y adequately. 

So,

When num >= 10 , (x-2) * (y-2) is larger than num-2

Then

dp[i] = max(dp[i-3]*1, dp[i-4]*2, ...dp[i-9]*7 )

Here is the code:


#include <stdio.h>
#include <string>
#include <iostream>
#include <map>
#include <string.h>
#include <vector>

using namespace std;

class Node {
public:
  int x,y;
  Node(int x = 0, int y = 0):x(x),y(y) {}
};
int findMaxK(int n) {
  int power = 2;
  double max = 0.0;
  int maxK = 0;
  while (n > 0) {
    n -= 2;
    double t = (double)n/power;
    double r = pow(t, (double)power);
    if (r > max) {
      maxK = power;
      max = r;
    }
    power++;
  }
  return maxK;
}
unsigned int f(int n) {
  if (n <= 7) return n;
  int k = findMaxK(n);

  int sum = n - 2*(k-1);
  unsigned int mul = 1;
  while (k > 0) {
    int avg = sum/k;
    mul *= avg;
    k--;
    sum -= avg;
  }
  return mul;
}


int g(int n) {
  int size = max(n, 9), i, j;
  vector<int> dp(n + 1, 0);
  int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 12};
  for (i = 0; i <= 9; ++i)
    dp[i] = arr[i];
  if (n <= 9)
    return dp[n];
  for (i = 9; i <= n; ++i) {
    dp[i] = dp[i - 3];
    for (j = 4; j <= 9; ++j)
      dp[i] = max(dp[i], dp[i - j] * (j - 2));
  }
  return dp[n];
}

int main() {
  int res1 = f(90);
  int res2 = g(90);
  return 0;
}

The function f is another method from leetcode, but I don't like it..

This question seemed like a brand new interview question from Google. Someone posted this problem on adiscussion board, and it generated a lot of discussions, which unfortunately none of them is really helpful in solving this problem. Here, I discuss my approach and solution to this problem, and just like those other tricky questions from a typical Google interview — the common pitfalls you might fall into.

One common strategy in problem solving is to always begin with small examples.

It is trivial to notice that for <= 6, N. But how about the case where = 7? Here is where the most common pitfall that most people would fall into (myself included).

Most people reason that for = 7, the answer is = 8, because the sequence S = { A, A, A, A, CTRL+A, CTRL+C, CTRL+V } produces a total of 8 A’s.

Wait, the copied text is still in the buffer after a paste operation. We could have applied CTRL+V twice to double the previous text, sweet! 

How about S = { A, A, A, CTRL+A, CTRL+C, CTRL+V, CTRL+V } which produces a total of 9 A’s?

Unfortunately, both of the above answers are incorrect, as the correct answer for N = 7 is M = 7. This is simply because the sequence of { CTRL+A, CTRL+C, CTRL+V } does not double the previous text. Why? Take a moment to let this to sink into your brain.

Answers for N up to 7 is easy, which is M = N. But how about N = 8?

For N = 8 the answer is M = 9, where S = { A, A, A, CTRL+A, CTRL+C, CTRL+V, CTRL+V, CTRL+V }.

For N = 9 the answer is M = 12, where S = { A, A, A, CTRL+A, CTRL+C, CTRL+V, CTRL+V, CTRL+V, CTRL+V }.

You might ask why all A’s are typed before the sequence of { CTRL+A, CTRL+C, CTRL+V } operations.

Assume that we could insert A’s at the back of some sequence of { CTRL+A, CTRL+C, CTRL+V } and yield a maximum sequence. If we take all the A’s from the back and insert it at the front, this modified sequence must yield a larger number of A’s, since the number of A’s is multipled from the beginning. Therefore, by contradiction, all A’s must always be inserted at the front to yield the maximum number of A’s. Similar for the case where A’s are inserted in the middle of the sequence.

Before we proceed further, we introduce the following notation:

  • Define 4A as a sequence of { A, A, A, A }. Therefore, 5A would then mean { A, A, A, A, A }.
  • Define 2D as a sequence of CTRL+A, CTRL+C, CTRL+V, CTRL+V, which simply means double the previous text. Note that 3D does not double the previous text, it actually triples the previous text.

With this notation in place, it is much easier to work with this problem. Using the above notation, we rewrite our answer for = 8 and = 9.

= 8, S = { 3A3D }, = 9.

= 9, S = { 3A4D }, = 12.

The value of M could be obtained simply by multiplying the numbers, isn’t that neat?

Working our way up:
= 10, S = { 4A4D }, = 16.

N = 11, S = { 5A4D }, = 20.

As you can see, the pattern here is pretty obvious, let’s summarize as follow:

  • The solution so far for > 7 is to find integers a and b such that ab yields the largest product, subjected to the condition where a+b = N-2.
  • Both and are easy to find, as the largest product is found when the difference of and is less than or equal to one.

Similarly,
= 12, S = { 5A5D }, = 25.
= 13, S = { 5A6D }, = 30.
= 14, S = { 6A6D }, = 36.

Be extra cautious for = 15.
When = 15, does the sequence { 6A7D } yields the maximum where = 42?

Imagine if you have a very large number of keystrokes to enter, does pressing CTRL+V forever gives you the maximum sequence? Remember, you can redo the entire { CTRL+A, CTRL+C, CTRL+V } operations again and potentially maximizes the sequence.

For = 15, the maximum sequence should be:
3A4D4D }, which yields = 48.

Similarly,
N = 16, = { 4A4D4D }, = 64.

N = 21, = { 3A4D4D4D }, = 192.

= 25, = { 4A5D5D5D }, = 500.
= 26, = { 5A5D5D5D }, = 625.
= 27, = { 3A4D4D4D4D }, = 768.

Let’s generalize the above:

M = MAX ( a 1 .  a 2 …  ak),

where 
a
1 + a2 + … + ak = n – 2(k-1)

To obtain M = MAX (a1 . a2 … ak),
it is necessary that the below condition must be met:

∀  ij ∈{ 1, 2, … ,  } : MAX ( |  ai –  aj | ) = 1.

To obtain M, we can first divide a1 + a2 + … + ak by k to obtain the average as a reference, and the rest should be straightforward.

Now the final problem lies in how to obtain the value of k efficiently. I am pretty sure this could be solved easily using Number Theory, but so far, my best solution is to use a brute force method to obtain k.

Below is the C++ code for my solution. It is pretty straightforward to output the sequence S. Given N, the functionf() returns the maximum value of M.





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值