HDU1085 Holding Bin-Laden Captive!
? HDU ? ? 解题记录 ? ? 生成函数 ? ? FFT|NTT ?    2018-01-18 09:13:18    521    0    0
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 1398 1028 2152 2082 
 

题目大意:有有限的1元、2元、5元的硬币,问最小不能被凑出的钱数是多少。

对于这道题我们构造生成函数:对于x^i前的系数表示取到i面值的方案。先求出只取1元、2元、5元时的函数(即被币值整除的次数系数为1),记做f1, f2, f5。那么对应得答案:y = f1*f2*f5。O(n ^ 2)。用FFT可以优化到O(n log n)(然后比n^2还慢)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<complex>
using namespace std;
const int maxn = 1e5 + 5;
typedef complex<double > E;
E f[3][maxn];
double Pi = acos(-1);
int n, num[3], m, m2, R[maxn];

void DFT(E * a, int type) {
	for(register int i = 0; i < n; ++i) if(i < R[i]) swap(a[i], a[R[i]]);
	for(register int i = 1; i < n; i <<= 1) {
		E Wn(cos(Pi / i), sin(Pi * type / i));
		for(register int p = i << 1, j = 0; j < n; j += p) {
			E w(1, 0);
			for(register int k = 0; k < i; ++k, w *= Wn) {
				E x = a[j + k], y = a[i + j + k] * w;
				a[j + k] = x + y, a[j + k + i] = x - y;
			}
		}
	}
}

int main() {
	while(1) {
		for(register int i = 0; i < 3; ++i) 
			scanf("%d", &num[i]);
		if(!(num[0] | num[1] | num[2])) break;
		m = num[0] * 1 + num[1] * 2 + num[2] * 5;
		for(register int i = 0; i <= num[0]; ++i) 
			f[0][i] = 1;
		for(register int i = 0; i <= num[1]; ++i) 
			f[1][i * 2] = 1;
		for(register int i = 0; i <= num[2]; ++i) 
			f[2][i * 5] = 1;
		for(n = 1, m2 = 0; n <= m; n <<= 1) ++m2;
		for(register int i = 1; i <= n; ++i) R[i] = (R[i >> 1] >> 1) | ((i & 1) << (m2 - 1));
		DFT(f[0], 1), DFT(f[1], 1), DFT(f[2], 1);
		for(register int i = 0; i <= n; ++i) f[0][i] *= f[1][i] * f[2][i];
		DFT(f[0], -1);
		for(register int i = 0; i <= n; ++i) 
			if(abs(f[0][i].real() / n - 0) < 0.01) {
				printf("%d\n", i);
				break;
			}
		memset(f, 0, sizeof(f));
	}
	return 0;
}

 

上一篇: HDU3734 Blocks

下一篇: BZOJ3771: Triple

521 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航