您的位置:首页 > 其它

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

2013-08-01 21:15 411 查看
给定一个正整数 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代码:

#include <stdio.h>


#include <math.h>


#include <iostream>


#include <cstdarg>


#include <algorithm>


#include <string.h>


#include <stdlib.h>


#include <string>


#include <list>


#include <vector>


#include <map>


#define LL long long


#define M(a) memset(a, 0, sizeof(a))


using namespace std;


 


void Clean(int count, ...)


{


va_list arg_ptr;


va_start (arg_ptr, count);


for (int i = 0; i < count; i++)


M(va_arg(arg_ptr, int*));


va_end(arg_ptr);


}


 


int res(int n)


{


return (n == 1) ? 1 : res(n / 2) + 1;


}


 


int main()


{


int n;


while (cin >> n)


cout << res(n) << endl;


return 0;


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: