题解:P1909 [NOIP2016 普及组] 买铅笔

这是一道很好的入门题,特别适合新手在刚学信奥的时候做。

思路

我们一个包装里有 $a$ 支笔,那我们有 $n$ 个人,那么我们需要 $\lceil n / a \rceil$ 包笔($\lceil x \rceil$ 表示对 $x$ 向上取整),而我们不够分的笔还要再买一包,因此要向上取整,但是 C++ 会自动向下取整,因此我们可以使用 ceil(x) 函数,这个函数可以对 $x$ 进行向上取整。

这里做一个拓展:

现在我们知道要买的包书了,那么我我们要计算它的价格,假设一包笔是 $b$ 元,那么我们对上述的式子进行总和,我们得出每一种包装的价格就是 $\lceil n / a \rceil \times b$ 元。

既然要求到最小值,那肯定要使用到 min(a, b); 函数,这个函数可以求出 $a$ 和 $b$ 的最小值。

这里做一个拓展:

而我们要求三个数的最小值,可以先求出两个数的最小值,再将求出来的最小值跟第三个数进行比较,就可以得出三个数的最小值了。

但是仅仅这样会出现错误,因为两个整数在进行运算时,得出来的结果也是整数,这时的向上取整是无效的(即对一个整数进行向上取整),因此我们可以的式子变为 $\lceil n \times 1.0 / a \rceil \times b$。

代码

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, a, ashuliang, ajiage, b, bshuliang, bjiage, c, cshuliang, cjiage;
int main()
{
    cin >> n >> ashuliang >> ajiage >> bshuliang >> bjiage >> cshuliang >> cjiage;
    a = ceil(n * 1.0 / ashuliang) * ajiage;
    b = ceil(n * 1.0 / bshuliang) * bjiage;
    c = ceil(n * 1.0 / cshuliang) * cjiage;
    cout << min(min(a, b), c) << endl;
    return 0;
}