UVa 11384 Help is needed for Dexter 正整数序列

给定一个正整数 n ,你的任务使用最少的操作次数把序列 1, 2, 3, …… , n 中的所有数都变成 0 。每次操作可以从序列中选择一个或者多个数,同时减去一个相同的正整数。比如,1, 2, 3 可以把 2 和 3 同时减小 2 ,得到 1, 0, 1 。

模拟几次就能看出做法了。

例如当 n = 6 的时候

0      -----      1  2  3  4  5  6

1      -----      1  2  3  0  1  2

2      -----      1  0  1  0  1  0

3      -----      0  0  0  0  0  0

再比如 n = 9 的时候

0      -----      1  2  3  4  5  6  7  8  9

1      -----      1  2  3  4  0  1  2  3  4

2      -----      1  2  0  1  0  1  2  0  1

3      -----      1  0  0  1  0  1  0  0  1

4      -----      0  0  0  0  0  0  0  0  0

通过这两组例子就能很容易的看出,我每次都把原有数列分成两份,1 ~ len / 2 , 和 (len / 2) + 1 ~ len两部分。然后每次都减去 len / 2 这么多,然后 len = len / 2,如此循环,直到最后把 1 减去,所用的次数就是最小的次数。

现在知道怎么做了,就可以继续分析题目了。

按照上面的方法,我们可以得到下表:

1         ----         1

2         ----         2

3         ----         2

4         ----         3

5         ----         3

6         ----         3

7         ----         3

8         ----         4

打表打到这里,可以很轻松的看到规律。1 个 1 , 2 个 2, 4 个 3 , 8 个 4 。。。以此类推,规律就是这样了。然后写一个递归就能找到答案了。

附AC代码:

   1: #include <stdio.h>
   2: #include <math.h>
   3: #include <iostream>
   4: #include <cstdarg>
   5: #include <algorithm>
   6: #include <string.h>
   7: #include <stdlib.h>
   8: #include <string>
   9: #include <list>
  10: #include <vector>
  11: #include <map>
  12: #define LL long long
  13: #define M(a) memset(a, 0, sizeof(a))
  14: using namespace std;
  15:  
  16: void Clean(int count, ...)
  17: {
  18:     va_list arg_ptr;
  19:     va_start (arg_ptr, count);
  20:     for (int i = 0; i < count; i++)
  21:         M(va_arg(arg_ptr, int*));
  22:     va_end(arg_ptr);
  23: }
  24:  
  25: int res(int n)
  26: {
  27:     return (n == 1) ? 1 : res(n / 2) + 1;
  28: }
  29:  
  30: int main()
  31: {
  32:     int n;
  33:     while (cin >> n)
  34:         cout << res(n) << endl;
  35:     return 0;
  36: }
原文地址:https://www.cnblogs.com/wuhenqs/p/3231254.html