您的位置:首页 > 其它

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

2017-09-04 15:35 411 查看
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

题意:告诉你一元的硬币有几个,两元的硬币有几个,五元的硬币有几个,问你最小的不能由它们所组成的价值是多少。

思路:母函数模板题,输入的三个数相当于就是三个因子的终止系数,然后对答案数组从小到大扫一遍,输出第一个为0的数就行了。

母函数模板:http://blog.csdn.net/kele52he/article/details/77834848

普通母函数模板

用时300ms

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
#include <functional>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9 + 5;
const int MAXN = 8005;
const int MOD = 30021;
const double eps = 1e-8;
const double PI = acos(-1.0);

int Num;//因子个数
int n1[MAXN];//n1[i]表示该乘积表达式第i个因子的起始系数
int n2[MAXN];//n2[i]表示该乘积表达式第i个因子的终止系数
int v[MAXN];//v[i]表示该乘积表达式第i个因子的权重
int P;//P是可能的最大指数
int a[MAXN], b[MAXN];//a为计算结果,b为中间结果。

void solve()
{
memset(a, 0, sizeof(a));
a[0] = 1;
for (int i = 1; i <= Num; i++)//循环每个因子
{
memset(b, 0, sizeof(b));
for (int j = n1[i]; j <= n2[i] && j*v[i] <= P; j++)//循环每个因子的每一项
for (int k = 0; k + j*v[i] <= P; k++)//循环a的每个项
b[k + j*v[i]] += a[k];//把结果加到对应位
memcpy(a, b, sizeof(b));//b赋值给a
}
}

int main()
{
Num = 3;
P = 8000;
n1[1] = 0;
n1[2] = 0;
n1[3] = 0;
v[1] = 1;
v[2] = 2;
v[3] = 5;
while (scanf("%d%d%d",&n2[1],&n2[2],&n2[3])!=EOF)
{
if (n2[1] == 0 && n2[2] == 0 && n2[3] == 0)
break;
solve();
for (int i = 1; i <= 8004; i++)
if (a[i] == 0)
{
printf("%d\n", i);
break;
}
}
}


优化母函数模板

用时30ms

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
#include <functional>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9 + 5;
const int MAXN = 8005;
const int MOD = 30021;
const double eps = 1e-8;
const double PI = acos(-1.0);

int Num;//因子个数
int n1[MAXN];//n1[i]表示该乘积表达式第i个因子的起始系数
int n2[MAXN];//n2[i]表示该乘积表达式第i个因子的终止系数
int v[MAXN];//v[i]表示该乘积表达式第i个因子的权重
int P;//P是可能的最大指数
int a[MAXN], b[MAXN];//a为计算结果,b为中间结果。
int last;

void solve2()
{
//初始化a,因为有last,所以这里无需初始化其他位
a[0] = 1;
last = 0;
for (int i = 1; i<=Num; i++)
{
int last2 = min(last + n2[i] * v[i], P);//计算下一次的last
memset(b, 0, sizeof(int)*(last2 + 1));//只清空b[0..last2]
for (int j = n1[i]; j <= n2[i] && j*v[i] <= last2; j++)//这里是last2
for (int k = 0; k <= last&&k + j*v[i] <= last2; k++)//这里一个是last,一个是last2
b[k + j*v[i]] += a[k];
memcpy(a, b, sizeof(int)*(last2 + 1));//b赋值给a,只赋值0..last2
last = last2;//更新last
}
}

int main()
{
int i;
Num = 3;
P = 8000;
n1[1] = 0;
n1[2] = 0;
n1[3] = 0;
v[1] = 1;
v[2] = 2;
v[3] = 5;
while (scanf("%d%d%d",&n2[1],&n2[2],&n2[3])!=EOF)
{
if (n2[1] == 0 && n2[2] == 0 && n2[3] == 0)
break;
solve2();
for ( i = 1; i <= last; i++)
if (a[i] == 0)
break;
printf("%d\n", i);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: