Project Euler 461
Project Euler 461
题目
Almost Pi
Let \(f_n(k)=e^{\frac{k}{n}}-1\), for all non-negative integers \(k\).
Remarkably, \(f_{200}(6)+f_{200}(75)+f_{200}(89)+f_{200}(226)= \underline{3.1415926}44529\dots\approx \pi\).
In fact, it is the best approximation of \(\pi\) of the form \(f_n(a)+f_n(b)+f_n(c)+f_n(d)\) for \(n=200\).
Let \(g(n)=a^2+b^2+c^2+d^2\) for \(a, b, c, d\) that minimize the error: \(|f_n(a)+f_n(b)+f_n(c)+f_n(d)-\pi|\) (where \(|x|\) denotes the absolute value of \(x\)).
You are given \(g(200)=6^2+75^2+89^2+226^2=64658\).
Find \(g(10000)\).
解决方案
可以看到,题中使用了\(4\)个\(f_n(i)\)进行逼近,那么我们考虑将这\(4\)个\(f_n(i)\)分成两对,然后使用meet-in-the-middle算法进行求解。
先将所有\(f_n(i)\)枚举并计算出来,注意计算到的\(f_n(i)>\pi\)时,停止枚举。
将以上的\(f_n(i)+f_n(j)(i\le j)\)枚举出来。当枚举到\(f_n(i)+f_n(j)>\pi\) 时,停止枚举。并记录所有的\((f_n(i)+f_n(j),i^2+j^2)\)二元组,存在数组\(p\)中。
将\(p\)中按照第一关键字进行排序。这一步骤是算法中耗时最长的一部分。
通过双指针法遍历数组\(p\),找出最优的解。
使用C++
内置的pair
比较慢,因此实现时重新自定义了一个结构体,整体效率大概增加了\(\dfrac{1}{3}\)。
代码
1 |
|