【组合数学】 Holding Bin-Laden Captive 详解

Holding Bin-Laden Captive:

题目链接:Holding Bin-Laden Captive!

“Given some Chinese Coins (硬币) (three kinds-- 1, 2, 5), and their number is num_1, num_2 and num_5 respectively, please output the minimum value that you cannot pay with given coins.”

Input

Input contains multiple test cases. Each test case contains 3 positive integers num_1, num_2 and num_5 (0<=num_i<=1000). A test case containing 0 0 0 terminates the input and this test case is not to be processed.

Output

Output the minimum positive value that one cannot pay with given coins, one line for one case.

题面大意:

题目真的又臭又长,没用的都删掉了。

有三种硬币,币值分别是1,2,5,现在给你三种硬币各自的数量,求最小的无法凑到的钱。       

比如三种硬币各有1,1,3个,那么最小的无论如何也没法凑到的就是4元。

分析:

 将这个问题转化为三个多项式相乘,不懂原理可以先看这篇文章:整数拆分问题(母函数)  

 而题目给的三个数num1,num2,num3限制的其实是三个多项式各自的项数:

(1+x+x^2+x^3+\cdot\cdot\cdot+x^{num1})\cdot(1+x^2+x^4+\cdot\cdot\cdot+x^{2×num2})\cdot(1+x^5+x^{10}+\cdot\cdot\cdot+x^{5×num3}) 

 三个多项式相乘会得到一个新的多项式,最小的无法凑到的钱也就是系数为0的最小的指数

  以上面硬币的个数1,1,3为例,则多项式:

    (1+x)\cdot(1+x^2)\cdot(1+x^5+x^{10}+x^{15})

=1+x+x^2+x^3+x^5+x^6+x^7+x^8+x^{10}+x^{11}+x^{12}+x^{13}+x^{15}+x^{16}+x^{17}+x^{18}

 可以发现x^4,x^9,x^{14},x^{19}……是不存在的(系数为0),那么这些钱都是无法凑到的,而其中最小的也就是我们要求的项x^4,其指数就是答案——4。

 那么这道题就转化为了三个多项式相乘

 代码:

 Poly和temp数组存放多项式,其下标i表示指数为i,存放的值为该项的系数 

 temp数组存放前两个多项式相乘的结果,Poly数组存放三个多项式相乘的结果,最后遍历Poly数组遇到的第一个值为0的元素,其指数就是答案。

  多项式相乘的模拟可以自己在纸上模拟一遍应该就能看懂了,两层循环各自控制一个多项式的项,其相乘表现为指数的相加。

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;

int main()
{
    int  num[4];
    while(~scanf("%d %d %d",&num[1],&num[2],&num[3])){
        if(!num[1]&&!num[2]&&!num[3])
             break;
        int temp[10005];
        int Poly[10005];
        memset(Poly,0,sizeof(Poly));
        memset(temp,0,sizeof(temp));

        for(int i=0;i<=num[1];i++)
            for(int j=0;j<=2*num[2];j+=2)
                         temp[i+j]+=1;;

        for(int i=0;i<=num[1]+2*num[2];i++){
            if(temp[i]>0){
                 for(int j=0;j<=5*num[3];j+=5)
                    Poly[i+j]+=temp[i];
            }
        }


        for(int i=1;i<=num[1]+2*num[2]+5*num[3]+1;i++){
           if(!Poly[i]){
             printf("%d\n",i);
             break;
           }
        }

    }
	return  0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值