UVA1646-Edge Case(递推+斐波那契数列)

Problem UVA1646-Edge Case

Time Limit: 3000 mSec

Problem Description

Input

For each test case, you get a single line containing one positive integer: n, with 3 ≤ n ≤ 10000.

 Output

For each test case, a row containing the number of matchings in Cn.

 Sample Input

3

4

100

Sample Output

4
7
792070839848372253127

题解:这个题一看样例就知道涉及高精度,不过只有加法,即便用C++写也没有什么难度,大致看了一下网上的题解,都是只说找规律没有证明(可能是我没翻到),因此在这里简单做个说明。

首先设最终结果为a[n],递推过程中需要引入一个中间序列b[n],b[n]的含义是强制让1、2两条边不连的匹配数。由此我们得到第一个递推式:

a[n] = b[n] + 2*b[n-1]

解释一下,n的时候的所有成立的情况可以分为三类,

1、1号边和2号边都不连

2、1号边连,2号边不连

3、2号边连,1号边不连

第一种情况自然对应b[n],第二种情况,如果1连,则1的左右两条边都不能连,这时看我引入的点P以及它连出的线段,它们将多边形分成上下两部分,只看上半部分,第二种情况的情况数就等于上半部分多边形强制让点P连的线段不连的情况数,即b[n-1],第三种情况类似。

我们再找一个关系式就可以递推了。从第一种情况入手,第一种情况等价于只有n-1个点时3号边不连,那我们就求强制让3不连的匹配数,发现不太好求,那就求强制让3连的匹配数,如果3号边连,那么它左右两条边都不能连,因此类似刚才的分析,匹配数等于b[n-1-1]=b[n-2],这样一来得到如下关系式:

b[n] = a[n-1]-b[n-2]

有了这两个关系式,解出数列a即可,基本操作,不再赘述。

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 const int maxn = 10000 + 100;
 6
 7 int Fib[maxn][15010];
 8 int n;
 9
10 void prepare()
11 {
12     Fib[3][0] = 1;
13     Fib[3][1] = 4;
14     Fib[4][0] = 1;
15     Fib[4][1] = 7;
16     for (int i = 5; i < maxn; i++)
17     {
18         for (int j = 1; j <= max(Fib[i - 1][0], Fib[i - 2][0]); j++)
19         {
20             Fib[i][j] += Fib[i - 1][j] + Fib[i - 2][j];
21             Fib[i][j + 1] = Fib[i][j] / 10;
22             Fib[i][j] %= 10;
23         }
24         Fib[i][0] = max(Fib[i - 1][0], Fib[i - 2][0]);
25         if (Fib[i][Fib[i][0] + 1])
26             Fib[i][0]++;
27     }
28 }
29
30 int main()
31 {
32     //freopen("input.txt", "r", stdin);
33     //freopen("output.txt", "w", stdout);
34     prepare();
35     while (~scanf("%d", &n))
36     {
37         for (int i = Fib[n][0]; i; i--)
38             printf("%d", Fib[n][i]);
39         printf("\n");
40     }
41     return 0;
42 }

原文地址:https://www.cnblogs.com/npugen/p/10405690.html

时间: 2024-12-10 15:23:51

UVA1646-Edge Case(递推+斐波那契数列)的相关文章

递推-斐波那契数列

描述 菲波那契数列是指这样的数列: 数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和.给出一个正整数a,要求菲波那契数列中第a个数是多少. 输入 第1行是测试数据的组数n,后面跟着n行输入.每组测试数据占1行,包括一个正整数a(1 <= a <= 20) 输出 输出有n行,每行输出对应一个输入.输出应是一个正整数,为菲波那契数列中第a个数的大小 样例输入 4 5 2 19 1 样例输出 5 1 4181 1 //听说这个数列是有公式的,然而渣渣不会,只能慢慢递推代码 #inclu

树上三角形(斐波那契数列神奇应用)

树上三角形(斐波那契数列神奇应用) Description给定一个大小为 n 的有点权树,需要支持两个操作.0:询问(u,v),能否在 u 到 v 的简单路径上取三个点,使这三个点的点权作为边长可以构成一个三角形.1:修改某个点的点权. Input第一行两个整数 n,q 表示树的点数和操作数.第二行 n 个整数表示 n 个点的初始的点权.接下来 n-1 行,每行两个整数 a,b,表示 a 是 b 的父亲.接下来 q 行,每行三个整数 op,a,b:若 op=0,则表示询问(a,b).若 op=1

十七、斐波那契数列 【递推思想(迭代思想)解决】

 递推思想本身并不跟函数有直接关系(虽然常常写在函数中). 其基本思路为: 为了解决一个"大"问题,根据现实逻辑,如果能够找到同类问题的一个"最小问题"的答案(通常是已知的),并且根据已知算法,又可以因此得到比最小问题"大一级"问题的答案. 而且,依次类推,又可以得到再大一级问题的答案,最终就可以得到"最大那个问题"(即要解决的问题)的答案. 可见,该思想的过程依赖与2个条件: 1,可知同类最小问题的答案: 2,大一级问题

使用递推和递归解决斐波那契数列问题~~~

/** * 使用递推的方式处理斐波那契数列 * @param sum * @param i * @return */ public static int findValue(int n){ if(n==1) { return 1; } if(n==2) { return 2; } int sum=1; int pre=1; for(int i=3;i<=n;i++) { int temp=sum; sum+=pre; pre=temp; } return sum; } /** * 采用递归的方式

Benelux Algorithm Programming Contest 2014 Final ACM-ICPC Asia Training League 暑假第一阶段第二场 E. Excellent Engineers-单点更新、区间最值-线段树 G. Growling Gears I. Interesting Integers-类似斐波那契数列-递推思维题

先写这几道题,比赛的时候有事就只签了个到. E. Excellent Engineers 传送门: 这个题的意思就是如果一个人的r1,r2,r3中的某一个比已存在的人中的小,就把这个人添加到名单中. 因为是3个变量,所以按其中一个变量进行sort排序,然后,剩下的两个变量,一个当位置pos,一个当值val,通过线段树的单点更新和区间最值操作,就可以把名单确定. 代码: 1 //E-线段树 2 #include<iostream> 3 #include<cstdio> 4 #incl

斐波那契数列实例讲解以及C++实现

斐波那契数列,又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.--在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)在现代物理.准晶体结构.化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从1963起出版了以<斐波纳契数列季刊>为名的一份数学杂志,用于专门刊载这方面的研究成果. 斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34,

斐波那契数列 Library

http://acm.tju.edu.cn/toj/showp3267.html3267.   Library Time Limit: 1.0 Seconds   Memory Limit: 65536KTotal Runs: 214   Accepted Runs: 96 Description As we all know, there are very long stairs before our library in campus III of our school. It is so

Fibonacci斐波拉契数列----------动态规划DP

n==10 20 30 40 50 46 体验一下,感受一下,运行时间 #include <stdio.h>int fib(int n){ if (n<=1)     return 1; else            return fib(n-1)+fib(n-2); }int main( ){ int n; scanf("%d",&n); printf("%d\n" ,fib(n) );} 先 n==10 20 30 40 50 46

《剑指Offer》题目——斐波拉契数列

题目描述:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项.(n<=39) 题目分析:如果使用简单的递归,很容易造成栈溢出.采用递推的方式即可. 代码: public class Fibonacci { public static int fibonacci(int n){ int res[] = new int[2]; res[0]=1; res[1]=1; int temp = 0; if(n==0) return 0; if(n<=2) return res[