f013: 砝码称重 (多重背包化01背包) + 南理工:砝码称重(贪心)

内容:

砝码称重(30分)

设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=1000),

要求:

    输入方式:a1  a2  a3  a4  a5  a6

             (表示1g砝码有a1个,2g砝码有a2个,…,20g砝码有a6个)

    输出方式:Total=N

             (N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况)

如输入:1_1_0_0_0_0   (注:下划线表示空格)

  输出:TOTAL=3  表示可以称出1g,2g,3g三种不同的重量。

来源 :

NOIP1996

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int main()
{
    bool dp[2000];
    int c[2000], num[7];
    int weight[7] = {0, 1, 2, 3, 5, 10, 20};
    //while(1)
    {
        int i, j, sum = 0;
        memset(dp,0,sizeof(dp));
        for(i = 1; i <= 6; i++)
        {
            scanf("%d",&num[i]);
            sum += num[i] * weight[i];
        }

        c[0] = 0;
        for(i = 1; i <= 6; i++)
        {
            for(j = 1; j < num[i]; num[i] -= j, j <<= 1)
                c[++c[0]] = weight[i] * j;
            if(num[i]) c[++c[0]] = weight[i] * num[i];
        }

        dp[0] = 1;
        for(i = 1; i <= c[0]; i++)
            for(j = sum; j >= c[i]; j--)
                dp[j] = (dp[j] || dp[j-c[i]]);

        int ret = 0;
        for(i = 1; i <= sum; i++)
            ret += dp[i];
        printf("Total=%d\n",ret);
    }
}



   1237 - 砝码称重

给你一些砝码,砝码的重量为1,3,9,27……(3^m),每个砝码都有无数多个。然后给你一架天平,一个物品,问你至少需要使用多少个砝码能称出物品的重量。问题描述

输入说明

多组测试样例,每组测试样例输入一个数n(0<n<2^31)表示物品的重量。

输出说明

对于每组测试样例输出至少需要使用砝码的数量。

输入样例

4
7
9

输出样例

2
3
1

题解:

      贪心,先放最大的。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
unsigned int power[35], cnt;

int main()
{
    unsigned int s = 1, limit = ((unsigned int)1<<31);
    for(cnt = 0; s <= limit; s *= 3)
        power[cnt++] = s;

    unsigned int n;
    while(scanf("%d",&n) != EOF)
    {
        unsigned int sum = 0, i;
        while(n > 0)
        {
            for(i = cnt - 1; i >= 0; i--)
                if(power[i] <= n) break;
            sum += n / power[i];
            n %= power[i];
        }
        printf("%d\n",sum);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值