首页 > 其他 > 详细

[HNOI2006]鬼谷子的钱袋

时间:2019-08-30 22:43:36      阅读:111      评论:0      收藏:0      [点我收藏+]

用二进制表示是最少的

把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;
}

[HNOI2006]鬼谷子的钱袋

原文:https://www.cnblogs.com/zi-nai-boboyang/p/11437140.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!