[HNOI2006]鬼谷子的钱袋

落花浮王杯 提交于 2019-11-29 00:46:07

用二进制表示是最少的

把m变成二进制,那么用m的二进制的位数那么多钱袋就可以了

比如m=11010

那么多个钱袋放1,10,100,1000,10000,最多可以达到11111

所以这道题就是求m的二进制位数

实际上本题就是“多重背包的二进制优化”,用二进制拆分就行,然而题中说两数除了1之外都不能相同,比如9,拆分后就是1 2 4 2, 不符合,对拆分序列进行排序,在拆分的时候遇到a[i] == a[i + 1] 的情况,就a[i]--, a[i + 1]++就行,最终得到拆分的方案。

AC代码如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;

int m, cnt, a[maxn];

int main()
{
    cin>>m;
    int x = 1;
    while(m - x > 0)  // 二进制拆分
    {
        m -= x;
        a[++cnt] = x;
        x <<= 1;
    }
    if(m!=0)  a[++cnt] = m;     //多余部分处理
    cout<<cnt<<endl;
    sort(a + 1, a + cnt + 1);
    for(int i = 1; i <= cnt; ++i)
    {
        if(a[i] == a[i + 1] && a[i] != 1) a[i]--, a[i + 1]++;
        cout<<a[i]<<" ";        // 打印拆分方案
    }
    return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!