Algorithm 您上次允许的击键是CtrlV,以确保您的最大击键数翻倍,因此,为了使其对齐,我们将在前三次击键后的任何额外击键中填充更多 for (i = 3 + n%3; i>0 && n>0; n--, i--) { print("a"); } for (; n>0; n = n-3) { print("ctrl-a"); print("ctrl-c"); print("ctrl-v"); }

Algorithm 您上次允许的击键是CtrlV,以确保您的最大击键数翻倍,因此,为了使其对齐,我们将在前三次击键后的任何额外击键中填充更多 for (i = 3 + n%3; i>0 && n>0; n--, i--) { print("a"); } for (; n>0; n = n-3) { print("ctrl-a"); print("ctrl-c"); print("ctrl-v"); },algorithm,Algorithm,编辑: #include <stdio.h> #include <string.h> #include <stdlib.h> void maxAprinted(int count, int maxKeys, int op, int printed, int pOutput, int *maxPrinted, char *seqArray) { if(count > maxKeys) return; if(count =

编辑:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void maxAprinted(int count, int maxKeys, int op, int printed, int pOutput, int *maxPrinted, char *seqArray)
{
    if(count > maxKeys)
        return;

    if(count == maxKeys)
    {
        if((*maxPrinted) < printed)
        {
            //new sequence found which is an improvement over last sequence
            (*maxPrinted) = printed;

            printf("\n");
            int i;
            for(i=0; i<maxKeys; i++)
                printf(" %c,",seqArray[i]);
        }

        return;
    }

    switch(op)
    {
        case 1:
        //A keystroke
            printed++;

            seqArray[count] = 'A';
            count++;
            break;

        case 2:
        //Ctrl-A and then Ctrl-C
            if((count+2) < maxKeys)
            {
                pOutput = printed;

                //comment the below statement to NOT factor 
                //in the assumption described above
                printed = 0;    
            }

            seqArray[count] = 'C';
            count++;
            seqArray[count] = 'S';
            count++;
            break;

        case 3:
        //Ctrl-V
            printed = printed + pOutput;

            seqArray[count] = 'V';
            count++;
            break;
    }

    maxAprinted(count, maxKeys, 1, printed, pOutput, maxPrinted, seqArray);
    maxAprinted(count, maxKeys, 2, printed, pOutput, maxPrinted, seqArray);
    maxAprinted(count, maxKeys, 3, printed, pOutput, maxPrinted, seqArray);    
}

int main()
{
    const int keyStrokes = 11;

    //this array stores the sequence of keystrokes
    char *sequence;
    sequence = (char*)malloc(sizeof(char)*(keyStrokes + 1));

    //stores the max count for As printed for a sqeuence
    //updated in the recursive call.
    int printedAs = 0;

    maxAprinted(0, keyStrokes,  1, 0, 0, &printedAs, sequence);

    printf(" :%d:", printedAs);

    return 0;
}    
这太可怕了,我完全超越了自己,没有为每一个副本考虑多个粘贴。

编辑2:


我相信粘贴3次是最好的,只要你有足够的按键次数。在5次击键中,将As的数量乘以4。这比使用4次击键乘以3好,也比使用6次击键乘以5好。我通过给每个方法相同的击键次数来进行比较,足够让每个方法在同一时间完成一个周期(60),让3乘法器执行15个周期,4乘法器执行12个周期,5乘法器执行10个周期。3^15=14348907,4^12=16777216,5^10=9765625。如果只剩下4次击键,则执行3次乘法器比再粘贴4次要好,基本上使之前的4次乘法器变为8次乘法器。如果只剩下3次击键,则最好使用2倍的乘法器。

下面使用OP的第二次编辑,粘贴不会替换现有文本

请注意以下几点:

  • ^A和^C可以被视为需要两次击键的单个操作,因为单独执行它们是没有意义的。事实上,我们可以用^K^V替换^A^C的所有实例,其中^K是一键“剪切”操作(让我们将其缩写为X)。我们将看到,处理^K比两个成本^A^C要好得多
  • 让我们假设剪贴板中有一个“A”开头。那么^V(让我们缩写为Y)严格优于A,我们可以从所有考虑中去掉后者。(在实际问题中,如果剪贴板开始为空,在接下来的步骤中,我们将用A替换Y,而不是^V,直到第一个X为止。)
因此,每个合理的击键序列都可以解释为一组由Xs分隔的y,例如yyyxyyxy。用V(s)表示序列s产生的‘A’的数量。然后V(nXm)=V(n)*V(m),因为X基本上用V(n)'A替换m中的每个Y

因此,复制粘贴问题同构于以下问题:“使用m+1个和为N-m的数字,最大化它们的乘积。”例如,当N=6时,答案是m=1和数字(2,3)。6=2*3=V(YYYXYY)=V(AA^A^C^V^V)(或V(yyyyyy)=V(AAA^A^C^V)

我们可以做一些观察:

对于固定值
m
,要选择的数字是
ceil((N-m)/(m+1))
floor((N-m)/(m+1))
(无论如何组合,都可以算出总和;更具体地说,您需要
(N-m)%(m+1)
ceil
和剩余的
floor
s)。这是因为,对于
a
(a+1)*(b-1)>=a*b

不幸的是,我没有找到一种简单的方法来找到
m
的值。如果这是我的采访,我会在这一点上提出两个解决方案:

备选案文1。循环所有可能的
m
。O(
n log n
)解决方案

C++代码:

long long ipow(int a, int b)
{
  long long val=1;
  long long mul=a;

  while(b>0)
    {
      if(b%2)
    val *= mul;
      mul *= mul;
      b/=2;
    }
  return val;
}

long long trym(int N, int m)
{
  int floor = (N-m)/(m+1);
  int ceil = 1+floor;
  int numceils = (N-m)%(m+1);
  return ipow(floor, m+1-numceils) * ipow(ceil, numceils);
}

long long maxAs(int N)
{
  long long maxval=0;
  for(int m=0; m<N; m++)
    {
      maxval = std::max(maxval, trym(N,m));
    }
  return maxval;
}
long-long ipow(内部a、内部b)
{
长val=1;
长mul=a;
而(b>0)
{
如果(b%2)
val*=mul;
mul*=mul;
b/=2;
}
返回val;
}
长-长trym(整数N,整数m)
{
内部楼层=(N-m)/(m+1);
int ceil=1+楼层;
整数=(N-m)%(m+1);
返回ipow(楼层,m+1个单元)*ipow(楼层,单元);
}
长-长最大值(整数N)
{
long-maxval=0;

对于(int m=0;m,通过使用marcog的解决方案,我发现了一个从
n=16
开始的模式。为了说明这一点,
n=24
n=29
,为了可读性,我将^a替换为s(选择),^C替换为C(复制),将^V替换为p(粘贴):

24: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P
       4   *    4    *    4    *    4    *    4     = 1024
25: A,A,A,A,S,C,P,P,P,S,C,P,P,S,C,P,P,S,C,P,P,S,C,P,P
       4   *    4    *   3   *   3   *   3   *   3    = 1296
26: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,S,C,P,P,S,C,P,P
       4   *    4    *    4    *   3   *   3   *   3    = 1728
27: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,S,C,P,P
       4   *    4    *    4    *    4    *   3   *   3    = 2304
28: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P
       4   *    4    *    4    *    4    *    4    *   3    = 3072
29: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P
       4   *    4    *    4    *    4    *    4    *    4     = 4096
在最初的4次击键后,理想的模式是选择、复制、粘贴、粘贴和重复。这将使每5次击键的次数乘以4次。如果这5次击键模式不能单独使用剩余的击键,那么一些4次击键模式(SCPP)将使用最后的击键,取代SCPPP(或根据需要移除其中一个粘贴)。每4次击键,4次击键模式的总数乘以3

这里使用这种模式的一些Python代码与marcog的解决方案得到的结果相同,但它是O(1)编辑的:这实际上是O(logn),这是由于指数运算,感谢IVlad指出的

def max_chars(n):
  if n <= 15:
    return (0, 1, 2, 3, 4, 5, 6, 9, 12, 16, 20, 27, 36, 48, 64, 81)[n]
  e3 = (4 - n) % 5
  e4 = n // 5 - e3
  return 4 * (4 ** e4) * (3 ** e3)
def最大字符数(n):
如果n可以在O(1)中求解:与斐波那契数一样,有一个公式可以计算打印的As数(以及击键顺序):


1) 我们可以简化问题描述:

  • 只有[A]、[C-A]+[C-C]、[C-v]和一个空的复制粘贴缓冲区
相等于

  • 在复制粘贴缓冲区中只有[C-a]+[C-C]、[C-v]和“a”

2) 我们可以将击键序列描述为{'*'、'V'、'V'}中N个字符的字符串,其中'V'表示[C-V],而'*'表示[C-a],而'V'表示[C-C]。例如:“VVV*VVV*VVV”

该字符串的长度仍然等于N

该字符串中Vv字长度的乘积等于生成的As数


3) 给定该字符串的固定长度N和固定数量的单词K,当所有单词的长度几乎相等时,结果将是最大的。它们的成对差异不超过±1

现在,如果给定N,最佳的K是多少


4) 假设我们想通过添加一个长度为L的单词来增加单词的数量,那么我们必须将L+1倍于任何前面的单词减少一个“v”。例如:“…*Vvv*Vvv*Vvv*Vvv”->”…*Vvv*Vvv*Vvv*Vvvv*Vvvv*Vvvv”

现在,最佳字长L是多少

(5*5*5*5*5)<(4*4*4*4*4)*4,(4*4*4*4)>(3*3*3)*3

=>最佳值为L=4


5) 假设,我们有足够大的N来生成一个包含许多长度为4的单词的字符串,但是a
long long ipow(int a, int b)
{
  long long val=1;
  long long mul=a;

  while(b>0)
    {
      if(b%2)
    val *= mul;
      mul *= mul;
      b/=2;
    }
  return val;
}

long long trym(int N, int m)
{
  int floor = (N-m)/(m+1);
  int ceil = 1+floor;
  int numceils = (N-m)%(m+1);
  return ipow(floor, m+1-numceils) * ipow(ceil, numceils);
}

long long maxAs(int N)
{
  long long maxval=0;
  for(int m=0; m<N; m++)
    {
      maxval = std::max(maxval, trym(N,m));
    }
  return maxval;
}
24: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P
       4   *    4    *    4    *    4    *    4     = 1024
25: A,A,A,A,S,C,P,P,P,S,C,P,P,S,C,P,P,S,C,P,P,S,C,P,P
       4   *    4    *   3   *   3   *   3   *   3    = 1296
26: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,S,C,P,P,S,C,P,P
       4   *    4    *    4    *   3   *   3   *   3    = 1728
27: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,S,C,P,P
       4   *    4    *    4    *    4    *   3   *   3    = 2304
28: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P
       4   *    4    *    4    *    4    *    4    *   3    = 3072
29: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P
       4   *    4    *    4    *    4    *    4    *    4     = 4096
def max_chars(n):
  if n <= 15:
    return (0, 1, 2, 3, 4, 5, 6, 9, 12, 16, 20, 27, 36, 48, 64, 81)[n]
  e3 = (4 - n) % 5
  e4 = n // 5 - e3
  return 4 * (4 ** e4) * (3 ** e3)
public int dp(int n) 
{
    int arr[] = new int[n];
    for (int i = 0; i < n; i++)
        arr[i] = i + 1;
    for (int i = 2; i < n - 3; i++) 
    {
        int numchars = arr[i] * 2;
        int j = i + 3;
        arr[j] = Math.max(arr[j], numchars);
        while (j < n - 1) 
        {
            numchars = numchars + arr[i];
            arr[++j] = Math.max(arr[j], numchars);
        }
    }
    return arr[n - 1];
}
        case 2:
        //Ctrl-A and then Ctrl-C
            if((count+2) < maxKeys)
            {
                pOutput = printed;

                //comment the below statement to NOT factor 
                //in the assumption described above
                printed = 0;    
            }
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void maxAprinted(int count, int maxKeys, int op, int printed, int pOutput, int *maxPrinted, char *seqArray)
{
    if(count > maxKeys)
        return;

    if(count == maxKeys)
    {
        if((*maxPrinted) < printed)
        {
            //new sequence found which is an improvement over last sequence
            (*maxPrinted) = printed;

            printf("\n");
            int i;
            for(i=0; i<maxKeys; i++)
                printf(" %c,",seqArray[i]);
        }

        return;
    }

    switch(op)
    {
        case 1:
        //A keystroke
            printed++;

            seqArray[count] = 'A';
            count++;
            break;

        case 2:
        //Ctrl-A and then Ctrl-C
            if((count+2) < maxKeys)
            {
                pOutput = printed;

                //comment the below statement to NOT factor 
                //in the assumption described above
                printed = 0;    
            }

            seqArray[count] = 'C';
            count++;
            seqArray[count] = 'S';
            count++;
            break;

        case 3:
        //Ctrl-V
            printed = printed + pOutput;

            seqArray[count] = 'V';
            count++;
            break;
    }

    maxAprinted(count, maxKeys, 1, printed, pOutput, maxPrinted, seqArray);
    maxAprinted(count, maxKeys, 2, printed, pOutput, maxPrinted, seqArray);
    maxAprinted(count, maxKeys, 3, printed, pOutput, maxPrinted, seqArray);    
}

int main()
{
    const int keyStrokes = 11;

    //this array stores the sequence of keystrokes
    char *sequence;
    sequence = (char*)malloc(sizeof(char)*(keyStrokes + 1));

    //stores the max count for As printed for a sqeuence
    //updated in the recursive call.
    int printedAs = 0;

    maxAprinted(0, keyStrokes,  1, 0, 0, &printedAs, sequence);

    printf(" :%d:", printedAs);

    return 0;
}    
N = 52

count = [0] * N
res = [[]] * N
clipboard = [0] * N

def maybe_update(i, new_count, new_res, new_clipboard):
  if new_count > count[i] or (
      new_count == count[i] and new_clipboard > clipboard[i]):
    count[i] = new_count
    res[i] = new_res
    clipboard[i] = new_clipboard

for i in range(1, N):
  # First option: type 'A'.
  # Using list concatenation for 'res' to avoid O(n^2) string concatenation.
  maybe_update(i, count[i - 1] + 1, res[i - 1] + ['A'], clipboard[i - 1])

  # Second option: type 'CTRL+V'.
  maybe_update(i, count[i - 1] + clipboard[i - 1],  res[i - 1] + ['v'],
               clipboard[i - 1])

  # Third option: type 'CTRL+A, CTRL+C, CTRL+V'.
  # Assumption: CTRL+V always appends.
  if i >= 3:
    maybe_update(i, 2 * count[i - 3],  res[i - 3] + ['acv'], count[i - 3])

for i in range(N):
  print '%2d %7d %6d %-52s' % (i, count[i], clipboard[i], ''.join(res[i]))
 0       0      0                                                     
 1       1      0 A                                                   
 2       2      0 AA                                                  
 3       3      0 AAA                                                 
 4       4      0 AAAA                                                
 5       5      0 AAAAA                                               
 6       6      3 AAAacv                                              
 7       9      3 AAAacvv                                             
 8      12      3 AAAacvvv                                            
 9      15      3 AAAacvvvv                                           
10      18      9 AAAacvvacv                                          
11      27      9 AAAacvvacvv                                         
12      36      9 AAAacvvacvvv                                        
13      45      9 AAAacvvacvvvv                                       
14      54     27 AAAacvvacvvacv                                      
15      81     27 AAAacvvacvvacvv                                     
16     108     27 AAAacvvacvvacvvv                                    
17     135     27 AAAacvvacvvacvvvv                                   
18     162     81 AAAacvvacvvacvvacv                                  
19     243     81 AAAacvvacvvacvvacvv                                 
20     324     81 AAAacvvacvvacvvacvvv                                
21     405     81 AAAacvvacvvacvvacvvvv                               
22     486    243 AAAacvvacvvacvvacvvacv                              
23     729    243 AAAacvvacvvacvvacvvacvv                             
24     972    243 AAAacvvacvvacvvacvvacvvv                            
25    1215    243 AAAacvvacvvacvvacvvacvvvv                           
26    1458    729 AAAacvvacvvacvvacvvacvvacv                          
27    2187    729 AAAacvvacvvacvvacvvacvvacvv                         
28    2916    729 AAAacvvacvvacvvacvvacvvacvvv                        
29    3645    729 AAAacvvacvvacvvacvvacvvacvvvv                       
30    4374   2187 AAAacvvacvvacvvacvvacvvacvvacv                      
31    6561   2187 AAAacvvacvvacvvacvvacvvacvvacvv                     
32    8748   2187 AAAacvvacvvacvvacvvacvvacvvacvvv                    
33   10935   2187 AAAacvvacvvacvvacvvacvvacvvacvvvv                   
34   13122   6561 AAAacvvacvvacvvacvvacvvacvvacvvacv                  
35   19683   6561 AAAacvvacvvacvvacvvacvvacvvacvvacvv                 
36   26244   6561 AAAacvvacvvacvvacvvacvvacvvacvvacvvv                
37   32805   6561 AAAacvvacvvacvvacvvacvvacvvacvvacvvvv               
38   39366  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacv              
39   59049  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvv             
40   78732  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvv            
41   98415  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvvv           
42  118098  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacv          
43  177147  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvv         
44  236196  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvv        
45  295245  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvvv       
46  354294 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacv      
47  531441 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvv     
48  708588 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvv    
49  885735 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvvv   
50 1062882 531441 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacv  
51 1594323 531441 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvv