目录
- 前置知识
- 问题描述
- 问题分析
- \(O(n)\)
- \(O(1)\)
前置知识
解决本题需要的前置知识是 二元一次方程组求解
但是就算还没有学到二元一次方程求解应该看一下下面的解释也能够看懂哒 (^_−)☆
问题描述
一只公鸡 \(5\) 元钱,一只母鸡 \(3\) 元钱,而一元钱能买 \(3\) 只小鸡。现有 \(n\) 元钱,想买 \(n\) 只鸡,问可买公鸡、母鸡、小鸡各几只,输出方案数(\(n \le 5 \cdot 10^6\))。
问题分析
首先,假设公鸡有 \(x\) 只,母鸡有 \(y\) 只,小鸡有 \(z\)
\[\begin{cases} x+y+z=n \\ 5x+3y+\frac{z}{3}=n \end{cases} \]
不妨设攻击数量 \(x\) 已知,可以推出母鸡数量和小鸡数量关于 \(x\)
\[\begin{cases} y + z = n - x \\ 3y + \frac{z}{3} = n - 5x \end{cases} \]
\[\begin{cases} y + z = n - x \\ 9y + z = 3n-15x \end{cases} \]
将上述两个式子相减可以消去 \(z\),得到 \(y\) 关于 \(x\)
\[8y = 2n-14x \]
\[\Rightarrow \]
\[y = \frac{n - 7x}{4} \]
再将 \(y\) 的值代入方程 \(y + z = n - x\)
\[z = \frac{3}{4} (n + x) \]
\(O(n)\)
此时可以发现一个很明显的 \(O(n)\) 的算法,就是从 \(1\) 到 \(n-2\) 枚举 \(x\),然后判断 \(y = \frac{n-7x}{4}\) 是不是一个整数且大于 \(0\),\(x = \frac{3}{4}(n+x)\)
因为已经保证 \(x+y+z = n\),且 \(x\) 和 \(z\) 都是正整数,所以只要保证 \(y \gt 0\)
示例程序:
\(O(1)\)
也有 \(O(1)\)
根据上面的推导:
\[\begin{cases} y = \frac{n - 7x}{4} \\ z = \frac{3}{4} (n + x) \end{cases} \]
\(y\)
\[y = \frac{n + x - 8x}{4} = \frac{n+x}{4} - 2x \]
可以发现,当 \(n + x\) 是 \(4\) 的倍数时 \(y\) 和 \(z\)
又因为需要 \(y \gt 0\),即 \(n - 7x \gt 0\),即 \(x \lt \frac{n}{7}\),考虑到实际运算时都是整数运算,所以不等式可以写成
\[x \le \lceil \frac{n}{7} \rceil - 1 \]
对应的 C++ 表达式为 x <= (n + 6) / 7 - 1
设 m = (n + 6) / 7 - 1
,则 \(x \le m\)
然后分情况讨论:
- 当
n % 4 == 0
时,需要 x % 4 == 0
,满足条件的公鸡的数量为 m / 4
- 当
n % 4 == 1
时,需要 x % 4 == 3
,满足条件的公鸡的数量为 (m + 1) / 4
- 当
n % 4 == 2
时,需要 x % 4 == 2
,满足条件的公鸡的数量为 (m + 2) / 4
- 当
n % 4 == 3
时,需要 x % 4 == 1
,满足条件的公鸡的数量为 (m + 3) / 4
归纳可知:满足条件的方案数为 (m + n % 4) / 4
种。
示例程序: