砝码称重:动态规划与母函数方法

设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其质量 ≤ 100g),求出用它们能称出的质量的种类数(不包括质量为0的情况)。

动态规划

设dp[100]数组为标记数组。当dp[i] = 0时, 表示质量为i的情况,目前没有被称出;当dp[i] = 1时,表示质量为i的情况已经称出。

当处理第j个砝码时, 其质量为w[j],有

if(dp[i - w[j]] == 1)
    dp[i] = 1;
int weight[];   //不同种类砝码的重量
int nums[];     //不同种类砝码对应的数量

int total = 0;  //当前可能称出的最大值;

//选取第j种类的砝码 
for(int j = 0; j < len; ++j)
{
    total += weight[j] * nums[j];
    for(int i = weight[j]; i <= total; ++i)
    {
        if(dp[i - weight[j]])
            dp[i] = 1;
    }
}

int cnt = 0;    //可能的称重
for(int k = 1; k <= total; ++k)
{
    if(dp[k])
        ++cnt;
}

母函数方法

设输入质量为w的砝码n个,则可以用母函数表示为:定义x(i)为x的i次方,
f(w, n) = 1 + x(1) + x(2) +… + x(n);
针对给定的例子,若输入的砝码(1g、2g、3g、5g、10g、20g)的个数分别为1、2、2、0、0、1,则有:
f1(1,1) = 1 + x(1);
f2(2, 2) = 1 + x(2) + x(4);
f3(3, 2) = 1 + x(3) + x(6);
f4(20, 1) = 1 + x(20);

F = f1(1, 1) * f2(2, 2) * f3(3, 2) * f4(20, 1)
= 1 + x(1) + x(2) + x(3) + x(4) + x(5) + x(6) + x(7) + x(8) + x(9) + x(10) + x(11) + x(20)
+ x(21) + x(22) + x(23) + x(24) + x(25) + x(26) + x(27) + x(28) + x(29) + x(30) + x(31)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值