HDU 1085 Holding Bin-Laden Captive!

Holding Bin-Laden Captive!

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 65536/32768 K (Java/Others)

Problem Description

We all know that Bin-Laden is a notorious terrorist, and he has disappeared for a long time. But recently, it is reported that he hides in Hang Zhou of China! 
“Oh, God! How terrible! ”

Don’t be so afraid, guys. Although he hides in a cave of Hang Zhou, he dares not to go out. Laden is so bored recent years that he fling himself into some math problems, and he said that if anyone can solve his problem, he will give himself up! 
Ha-ha! Obviously, Laden is too proud of his intelligence! But, what is his problem?
“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.”
You, super ACMer, should solve the problem easily, and don’t forget to take $25000000 from Bush!

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.

Sample Input

1 1 3
0 0 0

Sample Output

4

Author

lcy

Recommend

We have carefully selected several similar problems for you:  1171 2152 1709 2079 2110

Statistic | Submit | Discuss | Note

挺有意思的一道题,很常见(我为啥觉得常见嘞?)的一个定义。

给你三种硬币,面值分别为1,2,5。并给出它们各自的数量,请你求出最小的金额,无法用这些硬币的一个子集恰好表示。

这和FJOI的一道题很像,只是比那道题要弱很多,关于FJOI的那道题可以在我的Blog中搜索“福建神题”以查看详情。

那么,这么小的数据范围,做法显然多种多样,先讲蒟蒻(我)的做法好了。

显然这道题好多人给的标签都是生成函数,确实可以套一层生成函数的外壳就是了,但是其代码实现我觉得都用不着搬出生成函数来解释,而且无脑套生成函数会使得你的常数剧增(因为这题其实只是个01问题,好多人写模板都是直接求integer系数)。不过还是说一下。

这题按照题意,母函数就是$F(x)=(1+x+x^{2}+x^{3}+...+x^{k_{1}})(1+x^{2}+x^{4}+x^{6}+...+x^{2k_{2}})(1+x^{5}+x^{10}+x^{15}+...+x^{5k_{3}})=\sum_{i=0}^{k_{1}}{x^{i}}\sum_{i=0}^{k_{2}}{x^{2i}}\sum_{i=0}^{k_{3}}{x^{5i}}$,

然后就直接暴力做多项式乘法(貌似需要一点小小的优化,就是一开始边界不要给到8000什么的)就可以水过了。

然而我们不难看出这题只需要知道能否表示即可,并不需要计算具体的表示方案数,所以我们用一个bitset就可以表示所有系数是0还是其它了,这个不想手写可以用C++的STL,心疼Pascal童鞋一秒。

然后想起来,bitset的卷积,就是bitset的移位运算+或运算,所以还可以用移位运算优化一下,应该能快一些?(数据这么水,我也不知道能不能显现出来啊)

然后又想起来,bitset的卷积,写个优化算法就可以再除个log,那岂不是美滋滋?但是太难写了(偷个懒啦)。

所以贴上我的bitset暴力(母函数)的代码。

 1 #include <bitset>
 2 #include <cstdio>
 3
 4 int a, b, c;
 5
 6 std::bitset<8005> S;
 7
 8 signed main(void)
 9 {
10     while (scanf("%d%d%d", &a, &b, &c), a || b || c)
11     {
12         S.reset();
13
14         {
15             for (int i = 0; i <= a; ++i)
16                 for (int j = 0; j <= b; ++j)
17                     S.set(i + j * 2);
18         }
19
20         {
21             int lim = a + b * 2;
22
23             for (int i = lim; i >= 0; --i)if (S[i])
24                 for (int j = c; j >= 0; --j)
25                     S.set(i + j * 5);
26         }
27
28         int ans = 1;
29
30         while (S[ans])++ans;
31
32         printf("%d\n", ans);
33     }
34 }

然后来说说机智的做法。

如果当前有一个集合,可以表示$[1,a]$之内的所有数字,那么考虑向其中加入一个元素$b$会怎样。

如果$b\leq a+1$,那么新集合可以表示$[1,a+b]$内的所有数字。

反之,$a+1$将无法被任何子集表示,所以最小的不可表示数字就是$a+1$。

根据这个性质,我们设置$ans=1$,并令其不断逼近答案,每次取出小于等于$ans$的所有数字之和设为$sum$,

如果$sum<ans$,那么ans就是无法被表达的(这是显然的吧,取出来的加一起都够不到$ans$,而没取出来的随便一个都比$ans$大)。

反之,我们就令$ans=sum+1$,继续该过程。

这个算法的复杂度是有保证的。考虑算法如果没有结束,说明$ans=sum+1$,那么下一次取出的数字中一定要有一个在$[lastAns,nowAns]$之间的数字,否则将在下一次取数后结束。而这区间内的一个数字是大于$lastSum$,也就是说取出的集合中的数字之和至少翻番,所以总的取数次数是$O(log(\sum_{a_{i}\in S}{a_{i}}))$的,其中$ai$是给定集合$S$的元素。而我们的取数操作显然是$O(1)$的,所以算法复杂度就是$O(log(\sum_{a_{i}\in S}{a_{i}}))$。

下面给出这个算法的代码实现,在HDU上0MS通过。

 1 #include <cstdio>
 2
 3 int s[3] = {1, 2, 5}, c[3];
 4
 5 signed main(void)
 6 {
 7     while (scanf("%d%d%d", c, c + 1, c + 2), c[0] || c[1] || c[2])
 8     {
 9         int ans = 1;
10
11         while (true)
12         {
13             int sum = 0;
14
15             for (int i = 0; i < 3; ++i)
16                 if (s[i] <= ans)
17                     sum += s[i] * c[i];
18
19             if (ans > sum)
20                 break;
21             else
22                 ans = sum + 1;
23         }
24
25         printf("%d\n", ans);
26     }
27 }

@Author: YouSiki

时间: 2024-08-03 14:30:10

HDU 1085 Holding Bin-Laden Captive!的相关文章

hdu 1085 Holding Bin-Laden Captive!(母函数)

http://acm.hdu.edu.cn/showproblem.php?pid=1085 题意:1元,2元,5元的硬币分别有num[1],num[2],num[3]个.问用这些硬币不能组合成的最小钱数. 继续母函数. 有两个注意的地方: 对c2[]初始化的同时也要对c1[]初始化. 最后枚举到sum+1,因为存在[1,sum]都可以凑成的可能,这时输出sum+1. #include <stdio.h> #include <iostream> #include <map&g

hdu 1085 Holding Bin-Laden Captive! 母函数的基本运用,,还是不难的

Holding Bin-Laden Captive! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 16063    Accepted Submission(s): 7206 Problem Description We all know that Bin-Laden is a notorious terrorist, and he

HDU 1085 Holding Bin-Laden Captive!(母函数,或者找规律)

Holding Bin-Laden Captive! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 17653    Accepted Submission(s): 7902 Problem Description We all know that Bin-Laden is a notorious terrorist, and he h

HDU 1085 Holding Bin-Laden Captive!(母函数或背包DP)

Holding Bin-Laden Captive! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 23245    Accepted Submission(s): 10350 Problem Description We all know that Bin-Laden is a notorious terrorist, and he

HDU 1085 Holding Bin-Laden Captive!(DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1085 解题报告:有1,2,5三种面值的硬币,这三种硬币的数量分别是num_1,num_2,num_5,问你不能凑的钱的最小值是多少. DP,开一个这样的数组dp[i][3],然后dp[i][0]表示凑成 i 元钱需要dp[i][0]张1块的,需要dp[i][1]张两块的,dp[i][2]张5块的,然后依次往后递推,得到 i 的途径一共有三种,第一种是i-1加一张一块的,第二种是i-2加上1张两块的,

HDOJ/HDU 1085 Holding Bin-Laden Captive!(非母函数求解)

Problem Description We all know that Bin-Laden is a notorious terrorist, and he has disappeared for a long time. But recently, it is reported that he hides in Hang Zhou of China! "Oh, God! How terrible! " Don't be so afraid, guys. Although he hi

HDU 1085 Holding Bin-Laden Captive! 活捉本拉登(AC代码)普通型母函数

题意:有面值分别为1.2.5的硬币,分别有num_1.num_2.num_5个,问不能组成的最小面值是多少?(0<=每种硬币个数<=1000,组成的面值>0) 思路:母函数解决.只有3个括号要作乘法,分别代表面值1.2.5所能组成的情况.需要两个数组,所能组成的最大值为num_1+2*num_2+5*num_5.如果在这个范围内都能组成,那么最小不能组成的面值为num_1+2*num_2+5*num_5+1.若没有1分钱的硬币,那么不能组成的肯定是1了. 数组的用法:ans[]保存第一个

HDU 1085

想来想去都有bug 最后简单粗暴的一个一个来处理了 #include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<queue> #include<stack> #define mem(a,b) memset(a,b,sizeof(a)) #define ll __int64 #def

hdu 1085 给出数量限制的母函数问题 Holding Bin-Laden Captive!

Holding Bin-Laden Captive! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 17256    Accepted Submission(s): 7734 Problem Description We all know that Bin-Laden is a notorious terrorist, and he h