UVa 1546 - Complete the sequence!
Published on 2016-03-15描述
给定 , 以及 ,请你根据 个函数值,求出一个最高次项最小的通项公式,并输出 的值。输入保证存在最高次数不超过 的通项公式。
样例输入
4 6 3 1 2 3 4 5 6 8 2 1 2 4 7 11 16 22 29 10 2 1 1 1 1 1 1 1 1 1 2 1 10 3
样例输出
7 8 9 37 46 11 56 3 3 3 3 3 3 3 3 3 3
分析
老实说,给定前几项,我可以求出无数个通项公式,比如 ,看起来有 。事实上我可以令 ,这也是对的,可以无限制的构造,所以我们要求的是最小的通项公式。
当然可以枚举最高次项,使用高斯消元求出通项公式,可那麻烦了,我们介绍差分序列:
如果原序列是 ,那么它的一次差分序列就是 ,原序列两个数之间的差。二次差分序列就是 ,三次差分序列是 。
观察发现,如果最高次是 次,那么将在 次差分后达到 ,需要 个函数值,这也就是为什么题目保证存在最高次数不超过 的通项公式的原因。
既然已经知道一定会走向 0,那么把差分序列写成下三角型,递推一下很容易搞定后面的值。
代码
// Created by Sengxian on 3/15/16. // Copyright (c) 2016年 Sengxian. All rights reserved. // UVa 1546 差分序列 #include <algorithm> #include <iostream> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <vector> #include <queue> #include <stack> using namespace std; inline int ReadInt() { int n = 0, ch = getchar(); while (!isdigit(ch)) ch = getchar(); while (isdigit(ch)) n = (n << 1) + (n << 3) + ch - '0', ch = getchar(); return n; } const int maxn = 100 + 3; int n, m, a[maxn][maxn]; int main() { int caseNum = ReadInt(); while (caseNum--) { n = ReadInt(), m = ReadInt(); memset(a, 0, sizeof a); for (int i = 0; i < n; ++i) a[0][i] = ReadInt(); for (int i = 1; i < n; ++i) for(int j = 0; j < n - i; ++j) a[i][j] = a[i - 1][j + 1] - a[i - 1][j]; a[n][0] = 0; for(int j = 0; j < m; ++j) for(int i = n - 1; i >= 0; --i) a[i][j + n - i] = a[i][j + n - i - 1] + a[i + 1][j + n - i - 1]; for(int i = 0; i < m; ++i) printf("%d%c", a[0][n + i], i + 1 == m ? '\n' : ' '); } return 0; }