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限制的其实是三个多项式各自的项数:
三个多项式相乘会得到一个新的多项式,最小的无法凑到的钱也就是系数为0的最小的指数
以上面硬币的个数1,1,3为例,则多项式:
可以发现,,,……是不存在的(系数为0),那么这些钱都是无法凑到的,而其中最小的也就是我们要求的项,其指数就是答案——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;
}