CSU-ACM2017暑假集训比赛7 B

来源:互联网 发布:西安行知中学中考喜报 编辑:程序博客网 时间:2024/06/05 16:27

B - Raising Bacteria

You are a lover of bacteria. You want to raise some bacteria in a box.Initially, the box is empty. Each morning, you can put any number of bacteria into the box. And each night, every bacterium in the box will split into two bacteria. You hope to see exactly x bacteria in the box at some moment.What is the minimum number of bacteria you need to put into the box across those days?

Input

The only line containing one integer x (1 ≤ x ≤ 109).

Output

The only line containing one integer: the answer.

Example
Input

5Output2Input8Output1

Note

For the first sample, we can add one bacterium in the box in the first day morning and at the third morning there will be 4 bacteria in the box. Now we put one more resulting 5 in the box. We added 2 bacteria in the process so the answer is 2.For the second sample, we can put one in the first morning and in the 4-th morning there will be 8 in the box. So the answer is 1.

为使放入盒中的细菌数量最少,第一天肯定只放一个,并且之后加入时每次也只加入一个,充分利用细菌的增殖来增加细菌总数。又由于细菌数量在每天晚上倍增,而放入细菌的时间是某天早上,所以某天早上的细菌总数(放入新的细菌前)有以下两种情况:

f(k) f(k) f(k)=f(k1)×2    =[f(k1)+1]×2k

考虑某些天早上不放细菌,某些天早上放细菌,使得某天早上细菌数恰好是目标数目,或者再放入一个即达到目标数目,假定目标为 14,则有如下最优方案:第一天放一个,当晚盒中有两个细菌;第二天放一个,当晚盒中有六个细菌;第三天放一个,当晚盒中即有十四个细菌;第四天不放,达到目标。假定目标为 17,则有如下最优方案:第一天放一个,当晚盒中有两个细菌;第二天不放,当晚盒中有四个细菌;第三天不放,当晚盒中有八个细菌;第四天不放,当晚盒中有十六个细菌;第五天放一个,达到目标。
总结这两个情况的表达式:
  14=1×23+1×22+1×21+0×20  17=1×24+0×23+0×22+0×21+1×20

可以看出,为达到目标所需放入的最少细菌数目就是这个目标的二进制数中 1 的个数,使用一个循环统计它就行了。

#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <queue>using namespace std;int x;int check(int tar){    int ret = 0;    while(tar){        if(tar & 1)            ret++;        tar >>= 1;    }    return ret;}int main() {#ifdef TEST    freopen("test.txt", "r", stdin);#endif // TEST    while(cin >> x){        cout << check(x) << endl;    }    return 0;}
原创粉丝点击