Algorithms FAQ

Table of Contents

有一个数组,然后你和另外一个人两头开始取数字。每次你只能取两头里面的某一个数字。让你设计一种策略,使得你取的数字尽可能大

2个的话,先取则赢 3 1 3个的话,中间那个如果比两边和大,则先取必输,否则则先取必赢 2 4 1 4 1 2 1 2 4 4个的话 分成两组,奇数位一组,偶数位一组,那组大则先取哪组,先取必赢 1 2 3 4

现在可以推出规律了,分成两组,奇数位一组,偶数位一组,看哪组和最大,最大的话先取哪组,然后一直保持取那一组的数即可

比如 1 2 3 4 5 6 偶数位和比较大,先取6 ,对方只能取1或者5,取1你就取2,取5你就取4,保持对方取奇数位上的就行了

  1. 静下来,从2,3,4,5,试试,就找出规律啦
  2. 动态规划问题.

找最大和Max-gain(1,n),等价于找“比对手最多赢多少”max-diff(1,n) + max-diff(i,j) 为 1, A[i] - max-diff(i+1,j) 2, A[j] - max=diff(i,j-1) 的两个最大值边界— max-diff(i,i) = A[i] only one left, and it's A's turn.

用DP…反着做,O(N2)

p(i,j) = max { A[i] + min {p(i+2,j), p(i+1,j-1)}, A[j] + min {p(i,j-2), p(i+1,j-1)} }

Pascal’s Triangle

/* time complexity: O(n^2), space: O(n) */
void printPascal(int n)
{
  int arr[n];
  int i, j, k;
  for(i = 0; i < n; ++i){
    arr[i] = 1;
    for(j = i; j > 1; --j)
      arr[j - 1] += arr[j - 2];
    for(k = 0; k <= i; ++k)
      printf("%d ",arr[k]);
    printf("\n");
  }
}

/* time: O(n^2), space: O(1) */
/* C(line, i) = line * .. *(line - i - 1) / i!
   C(line, i+1) = line * .. * (line - i) / (i + 1)!
   C(line, i+1) = C(line, i) * (line - i) / (i + 1)
*/
void printPascal(int n)
{
  int arr[n];
  int i, j;
  int C;
  for(i = 0; i < n; ++i){
    C = 1;
    for(j = 0; j <=i ; ++j){
      printf("%d ", C);
      C = C * (i - j) / (j + 1);
    }
    printf("\n");
  }
}

Author: Shi Shougang

Created: 2015-03-05 Thu 23:21

Emacs 24.3.1 (Org mode 8.2.10)

Validate