project euler 101 Optimum polynomial
题目
https://projecteuler.net/problem=101
大意
给你一个多项式表达式
然后 只对前面几项 进行最小幂次拟合,拟合的函数第一个和原函数 不同的输出值的和
原题目很简单,11x11的Vandermonde矩阵求个逆矩阵,甚至都不用处理分数 就搞完了
hackerrank
然后我发现了这个
https://www.hackerrank.com/contests/projecteuler/challenges/euler101/problem
直接把 矩阵拉到了 3000x3000,然后 多项式的系数是 传入的
首先Vandermonde就需要一个高效求逆的办法,最后再O(n^2)算算
高效求逆?
为什么要, 因为 我们有了原表达式,要去做拟合 实际就是
${\begin{pmatrix}
{a_0}\\
{a_1}\\
{a_2}\\
{\vdots}\\
{a_{n-1}}\\
\end{pmatrix}
}^T\begin{pmatrix}
{1}&{1}&{\cdots}&{1}\\
{x_{0}}&{x_{1}}&{\cdots}&{x_{n-1}}\\
{x_{0}^2}&{x_{1}^2}&{\cdots}&{x_{n-1}^2}\\
{\vdots}&{\vdots}&{}&{\vdots}\\
{x_{0}^{n-1}}&{x_{1}^{n-1}}&{\cdots}&{x_{n-1}^{n-1}}\\
\end{pmatrix}={
\begin{pmatrix}
{y_0}\\
{y_1}\\
{y_2}\\
{\vdots}\\
{y_{n-1}}
\end{pmatrix}}^T$
要去计算 左侧的a,如果能快速求逆,那么有
${\begin{pmatrix}
{a_0}\\
{a_1}\\
{a_2}\\
{\vdots}\\
{a_{n-1}}\\
\end{pmatrix}}^T
={\begin{pmatrix}
{y_0}\\
{y_1}\\
{y_2}\\
{\vdots}\\
{y_{n-1}}
\end{pmatrix}}^T
\begin{pmatrix}
{1}&{1}&{\cdots}&{1}\\
{x_{0}}&{x_{1}}&{\cdots}&{x_{n-1}}\\
{x_{0}^2}&{x_{1}^2}&{\cdots}&{x_{n-1}^2}\\
{\vdots}&{\vdots}&{}&{\vdots}\\
{x_{0}^{n-1}}&{x_{1}^{n-1}}&{\cdots}&{x_{n-1}^{n-1}}\\
\end{pmatrix}^{-1}$
也就是求完逆以后,只需要O(n^2)来得到a
$V(x_0,x_1,\cdots ,x_{n-1})=\begin{bmatrix} {1}&{1}&{\cdots}&{1} \\
{x_{0}}&{x_{1}}&{\cdots}&{x_{n-1}}\\
{x_{0}^2}&{x_{1}^2}&{\cdots}&{x_{n-1}^2}\\
{\vdots}&{\vdots}&{}&{\vdots}\\
{x_{0}^{n-1}}&{x_{1}^{n-1}}&{\cdots}&{x_{n-1}^{n-1}}\\ \end{bmatrix}$
有 $ V(x_0,x_1,\cdots ,x_{n-1})=\prod _{n > i > j \geq 0}(x _{i}-x _{j})$
众所周知 $A^{-1} = \frac{1}{|A|} A^*$,然而 这暴力算是4次方复杂度,似乎比玩高斯消元3次方还要久
换个方法 拉格朗日插值
想法很简单 比如过点 (1,1) (4,7) (9,100)的二次函数
直接表达式$f(x) = k_1(x-4)(x-9)+k_2(x-1)(x-9) + k_3(x-1)(x-4)$
注意到x取其中一个点时,求和的表达式只有一个不为0
也很明显 $k_i = y_i\prod\limits_{j\not =i}\dfrac{1}{x_i-x_j}$
$f(x)=\sum\limits_{i=0}^ky_i\prod\limits_{j\not =i}\dfrac{x-x_j}{x_i-x_j}$, 也可以知道它的逆矩阵 就是求和每一部分 的展开式的系数,(令 $y = [0 … 0 1 0 … 0]$ 即可知
回到题目$x_i = i+1, y_i = \sum\limits_{p=0}^n A_p(i+1)^p$
$f(x)=\sum\limits_{i=0}^k[y_i\prod\limits_{j\not =i}\dfrac{x-j-1}{i-j}]$
注意到 我们其实只需要求 $f(k+1)$ , 计算 所有$y_i$ O(n^2), 但是右侧看似复杂的$x_i$乘积,因为这里的取值,变成了只需要做阶乘运算即可。可类似前缀和。 再配合一点乘法逆元即可
代码
1 | N = 0 |
至此 我们通过了较难版本的hackerrank 上的pe101