Project Euler 101 :Optimum polynomial 最优多项式
If we are presented with the first k terms of a sequence it is impossible to say with certainty the value of the next term, as there are infinitely many polynomial functions that can model the sequence.
As an example, let us consider the sequence of cube numbers. This is defined by the generating function,
un = n3: 1, 8, 27, 64, 125, 216, …
Suppose we were only given the first two terms of this sequence. Working on the principle that “simple is best” we should assume a linear relationship and predict the next term to be 15 (common difference 7). Even if we were presented with the first three terms, by the same principle of simplicity, a quadratic relationship should be assumed.
We shall define OP(k, n) to be the nth term of the optimum polynomial generating function for the first k terms of a sequence. It should be clear that OP(k, n) will accurately generate the terms of the sequence for n ≤ k, and potentially the first incorrect term (FIT) will be OP(k, k+1); in which case we shall call it a bad OP(BOP).
As a basis, if we were only given the first term of sequence, it would be most sensible to assume constancy; that is, for n ≥ 2, OP(1, n) = u1.
Hence we obtain the following OPs for the cubic sequence:
| OP(1, n) = 1 | 1, 1, 1, 1, … |
| OP(2, n) = 7n−6 | 1, 8, 15, … |
| OP(3, n) = 6n2−11n+6 | 1, 8, 27, 58, … |
| OP(4, n) = n3 | 1, 8, 27, 64, 125, … |
Clearly no BOPs exist for k ≥ 4.
By considering the sum of FITs generated by the BOPs (indicated in red above), we obtain 1 + 15 + 58 = 74.
Consider the following tenth degree polynomial generating function:
un = 1 − n + n2 − n3 + n4 − n5 + n6 − n7 + n8 − n9 + n10
Find the sum of FITs for the BOPs.
如果我们知道了一个数列的前k项,我们仍无法确定地给出下一项的值,因为有无穷个多项式生成函数都有可能是这个数列的模型。
例如,让我们考虑立方数的序列,它可以用如下函数生成,
un = n3: 1, 8, 27, 64, 125, 216, …
如果我们只知道数列的前两项,秉承“简单至上”的原则,我们应当假定这个数列遵循线性关系,并且预测下一项为15(公差为7)。即使我们知道了数列的前三项,根据同样的原则,我们也应当首先假定数列遵循二次函数关系。
给定数列的前k项,定义OP(k, n)是由最优多项式生成函数给出的第n项的值。显然OP(k, n)可以精确地给出n ≤ k的那些项,而可能的第一个不正确项(First Incorrect Term,简记为FIT)将会是OP(k, k+1);如果事实的确如此,我们称这个多项式为坏最优多项式(Bad OP,简记为BOP)。
在最基本的情况下,如果我们只得到了数列的第一项,我们应当假定数列为常数,也就是说,对于n ≥ 2,OP(1, n) = u1。
由此,我们得到了立方数列的最优多项式如下:
| OP(1, n) = 1 | 1, 1, 1, 1, … |
| OP(2, n) = 7n−6 | 1, 8, 15, … |
| OP(3, n) = 6n2−11n+6 | 1, 8, 27, 58, … |
| OP(4, n) = n3 | 1, 8, 27, 64, 125, … |
显然,当k ≥ 4时不存在坏最优多项式。
所有坏最优多项式的第一个不正确项(用红色标示的数)之和为1 + 15 + 58 = 74。
考虑下面这个十阶多项式生成函数:
un = 1 − n + n2 − n3 + n4 − n5 + n6 − n7 + n8 − n9 + n10
求其所有坏最优多项式的第一个不正确项之和。
解题
mathblog 提到拉格朗日多项式,突然明白了。
wiki中拉格朗日多项式的定义,在数值计算方法中叫拉格朗日差值函数

上面第k+1项就是所求的答案,至于为什么?已知的点很显然能够准确的预测出来,对于未知的点,为什么第k+1个点不能够预测对?
根据上面博客中写的程序,我记忆中本科时候好像写过这个程序的。
Java
package Level4;
public class PE0101{
public static void run(){
Lagrange();
}
public static void Lagrange(){
long[] coef = {1,-1,1,-1,1,-1,1,-1,1,-1,1};
Polynomial poly = new Polynomial(coef);
long[] y = new long[coef.length];
for(int i=0;i<y.length;i++)
y[i] = poly.evaluate(i+1);
long fits = 0;
for(int n=1;n<=coef.length -1;n++){
long result = 0;
for(int i =1;i<=n;i++){
long tmp1 = 1;
long tmp2 = 1;
for(int j=1;j<=n;j++){
if(i==j)
continue;
else{
tmp1 *= n + 1-j;
tmp2 *= i-j;
}
}
result +=tmp1*y[i-1]/tmp2;
}
fits +=result;
}
System.out.println(fits);
}
public static void main(String[] args){
long t0 = System.currentTimeMillis();
run();
long t1 = System.currentTimeMillis();
long t = t1 - t0;
System.out.println("running time="+t/1000+"s"+t%1000+"ms");
// 37076114526
// running time=0s1ms
}
}
class Polynomial{
private long[] coef;
public int Degree;
public Polynomial(int deg){
Degree = deg;
coef = new long[deg+1];
}
public Polynomial(long[] coef){
Degree = coef.length - 1;
this.coef = coef;
}
public long get(int i){
return coef[i];
}
public void set(int i,long value){
coef[i] = value;
}
public long evaluate(long x){
long result =0;
for(int i= this.Degree;i>=0;i--){
result = result *x +get(i);
}
return result;
}
}
Python
# coding=gbk import time as time
import re
import math def run():
y = ploy()
fits = 0
for n in range(1,11):
res = 0
for i in range(1,n+1):
tmp1 = 1
tmp2 = 1
for j in range(1,n+1):
if i==j:
continue
else:
tmp1 *= (n+1-j)
tmp2 *= (i-j)
res += tmp1*y[i-1]/tmp2
fits += res
print res
def ploy():
coef = [1,-1,1,-1,1,-1,1,-1,1,-1,1]
y = list() for n in range(1,11):
res = 1
m = n
for i in range(1,11):
res = res + coef[i] * m
m *=n
y.append(res)
print y
return y t0 = time.time()
run()
t1 = time.time()
print "running time=",(t1-t0),"s"
Project Euler 101 :Optimum polynomial 最优多项式的更多相关文章
- Python练习题 048:Project Euler 021:10000以内所有亲和数之和
本题来自 Project Euler 第21题:https://projecteuler.net/problem=21 ''' Project Euler: Problem 21: Amicable ...
- Python练习题 034:Project Euler 006:和平方与平方和之差
本题来自 Project Euler 第6题:https://projecteuler.net/problem=6 # Project Euler: Problem 6: Sum square dif ...
- [project euler] program 4
上一次接触 project euler 还是2011年的事情,做了前三道题,后来被第四题卡住了,前面几题的代码也没有保留下来. 今天试着暴力破解了一下,代码如下: (我大概是第 172,719 个解出 ...
- Python练习题 029:Project Euler 001:3和5的倍数
开始做 Project Euler 的练习题.网站上总共有565题,真是个大题库啊! # Project Euler, Problem 1: Multiples of 3 and 5 # If we ...
- Project Euler 9
题意:三个正整数a + b + c = 1000,a*a + b*b = c*c.求a*b*c. 解法:可以暴力枚举,但是也有数学方法. 首先,a,b,c中肯定有至少一个为偶数,否则和不可能为以上两个 ...
- Project Euler 44: Find the smallest pair of pentagonal numbers whose sum and difference is pentagonal.
In Problem 42 we dealt with triangular problems, in Problem 44 of Project Euler we deal with pentago ...
- project euler 169
project euler 169 题目链接:https://projecteuler.net/problem=169 参考题解:http://tieba.baidu.com/p/2738022069 ...
- 【Project Euler 8】Largest product in a series
题目要求是: The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × ...
- Project Euler 第一题效率分析
Project Euler: 欧拉计划是一系列挑战数学或者计算机编程问题,解决这些问题需要的不仅仅是数学功底. 启动这一项目的目的在于,为乐于探索的人提供一个钻研其他领域并且学习新知识的平台,将这一平 ...
随机推荐
- C++异常机制知识点
在这里总结一下,C++中的异常机制,以及如何使用异常的知识点 C++中处理异常的过程是这样的:在执行程序发生异常,可以不在本函数中处理,而是抛出一个错误信息,把它传递给上一级的函数来解决,上一级解决 ...
- html表格属性
一.在表格中插入文字及图片 1.把图片及文字分开到不同的[tr]标签表格内. <html> <body> <table border="1" widt ...
- 使用Log4j进行日志操作
使用Log4j进行日志操作 一.Log4j简介 (1)概述 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接字服 ...
- 软件工程随堂小作业—— 寻找“水王”(C++)
一.设计思路 (1)输入发帖ID记录表 (2)从第一个ID开始,与后续的发帖ID进行比较,若相同计数器则加一,否则减一.若计数器的数值被减为零,则重新选取当前ID开始记录比较. (3)输出结果 二.源 ...
- gmail邮箱怎么批量删除邮件
转载:http://jingyan.baidu.com/article/9f7e7ec056cbcd6f2815543c.html 首先打开gmail邮箱,随便打开一封邮件,找到发件人邮件地址,复制, ...
- curl get started
-v 显示整个通信过程 -L 自动处理目标网址的自动跳转如301跳转 -i 显示头部信息 -d 发送表单信息 -X HTTP动词 -F 文件上传 -A User Agent字段 -b cookie - ...
- JS 学习笔记--3--数据类型
1.typeof 操作符 用来获取变量或者字面量的类型,也可以typeof(x);但是typeof并非内置函 数,而是一个操作符变量2.JS 一共6种类型 Undefined/Null/Boolean ...
- Least Common Ancestors 分类: ACM TYPE 2014-10-19 11:24 84人阅读 评论(0) 收藏
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- 5-Highcharts曲线图之轴反转
<!DOCTYPE> <html lang='en'> <head> <title>5-Highcharts曲线图之轴反转</title> ...
- JS 数组的基础知识
数组 一.定义 1.数组的文字定义 广义上说,数组是相同类型数据的集合.但是对于强类型语言和弱类型语言来说其特点是不一样的.强类型语言数组和集合有以下特点. 数组强类型语言:1.数组里面只能存放相同数 ...