• 算法与数据结构---7.2、跳台阶-高精度加法


    算法与数据结构---7.2、跳台阶-高精度加法

    一、总结

    一句话总结:

    a、这个跳台阶的问题里面没有取模,n大概40多的时候结果就超过int了,而本题n等于5000,所以要用高精度,
    b、而因为递推关系式f(n)=f(n-1)+f(n-2)里面是加法,所以用高精度加法
     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 //高精度数对应的结构体
     7 struct BigNum{
     8     int length=0;
     9     int v[5000];
    10     BigNum(){
    11         memset(v,0,sizeof(v));
    12     }
    13 };
    14 
    15 //高精度加法
    16 BigNum add(BigNum a,BigNum b){
    17     BigNum ans;
    18     ans.length=max(a.length,b.length);
    19     //逐位相加
    20     for(int i=0;i<=ans.length-1;i++){
    21         ans.v[i]=a.v[i]+b.v[i];
    22     }
    23     //处理进位
    24     for(int i=0;i<=ans.length-1;i++){
    25         if(ans.v[i]/10){
    26             ans.v[i+1]+=ans.v[i]/10;
    27             ans.v[i]%=10;
    28         }
    29     }
    30     //判断最高位的数
    31     if(ans.v[ans.length]) ans.length++;
    32     return ans;
    33 }
    34 
    35 
    36 int main(){
    37     int n;
    38     BigNum a,b,c;
    39     cin>>n;
    40     //1、确定初始值
    41     a.length=1;b.length=1;
    42     a.v[0]=1;
    43     b.v[0]=2;
    44     //2、循环做递推,3-n
    45     for(int i=3;i<=n;i++){
    46         //F(n)=F(n-1)+F(n-2)
    47         c=add(b,a);
    48         //保留f(n)和f(n-1)做下一轮的f(n-1)和f(n-2)
    49         a=b;
    50         b=c;
    51     }
    52     if(n==0) cout<<0<<endl;
    53     else if(n==1) cout<<1<<endl;
    54     else if(n==2) cout<<2<<endl;
    55     else{
    56         for(int i=c.length-1;i>=0;i--){
    57             cout<<c.v[i];
    58         }
    59         cout<<endl;
    60     }
    61     return 0;
    62 }

    二、跳台阶

    博客对应课程的视频位置:7.2、跳台阶-高精度加法
    https://www.fanrenyi.com/video/27/285

    1、题目描述

    题目描述
    有N级的台阶,你一开始在底部,
    每次可以向上跳一步或者跳两步,
    问到达第N级台阶总共有多少种不同方式。

    输入格式
    一个数字,楼梯数。

    输出格式
    走的方式几种。

    输入输出样例
    输入
    4
    输出
    5

    数据范围
    60%,N<=50
    100%,N<=5000


    题目位置:
    P1255 数楼梯 - 洛谷 | 计算机科学教育新生态
    https://www.luogu.com.cn/problem/P1255

    2、分析

    分析:
    第1级台阶有一种方式
    第2级台阶有两种方式

    第3级台阶可以由第1阶走两步或第2阶走一步得出。1+2=3
    第4级台阶由第2阶走两步或第3阶走一步得出。2+3=5
    第5级台阶由第3阶走两步或第4阶走一步得出。3+5=8
    ...
    所以
    第n级台阶由第n-2阶走两步或第n-1阶走一步得出。

    所以如果用 f(n)表示跳到第n级台阶的总方式数
    所以 f(n)=f(n-1)+f(n-2)

    3、没高精度只能过5个点

    本题的考点除了斐波那契数列,还考高精度,没写高精度只能过5个点

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int main(){
     5     int n;
     6     int a,b,c;
     7     cin>>n;
     8     //1、确定初始值
     9     a=1;
    10     b=2;
    11     //2、循环做递推,3-n
    12     for(int i=3;i<=n;i++){
    13         //F(n)=F(n-1)+F(n-2)
    14         c=b+a;
    15         //保留f(n)和f(n-1)做下一轮的f(n-1)和f(n-2)
    16         a=b;
    17         b=c;
    18     }
    19     if(n==0) cout<<0<<endl;
    20     else if(n==1) cout<<1<<endl;
    21     else if(n==2) cout<<2<<endl;
    22     else cout<<c<<endl;
    23     return 0;
    24 }

    4、加上高精度过所有点

    高精度加法,因为递推关系式里面就是加法:

    f(n)=f(n-1)+f(n-2)
    高精度加法位置:算法疑难(c++实现)---3、高精度加法 - 范仁义 - 博客园
    https://www.cnblogs.com/Renyi-Fan/p/13066540.html
     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 //高精度数对应的结构体
     7 struct BigNum{
     8     int length=0;
     9     int v[5000];
    10     BigNum(){
    11         memset(v,0,sizeof(v));
    12     }
    13 };
    14 
    15 //高精度加法
    16 BigNum add(BigNum a,BigNum b){
    17     BigNum ans;
    18     ans.length=max(a.length,b.length);
    19     //逐位相加
    20     for(int i=0;i<=ans.length-1;i++){
    21         ans.v[i]=a.v[i]+b.v[i];
    22     }
    23     //处理进位
    24     for(int i=0;i<=ans.length-1;i++){
    25         if(ans.v[i]/10){
    26             ans.v[i+1]+=ans.v[i]/10;
    27             ans.v[i]%=10;
    28         }
    29     }
    30     //判断最高位的数
    31     if(ans.v[ans.length]) ans.length++;
    32     return ans;
    33 }
    34 
    35 
    36 int main(){
    37     int n;
    38     BigNum a,b,c;
    39     cin>>n;
    40     //1、确定初始值
    41     a.length=1;b.length=1;
    42     a.v[0]=1;
    43     b.v[0]=2;
    44     //2、循环做递推,3-n
    45     for(int i=3;i<=n;i++){
    46         //F(n)=F(n-1)+F(n-2)
    47         c=add(b,a);
    48         //保留f(n)和f(n-1)做下一轮的f(n-1)和f(n-2)
    49         a=b;
    50         b=c;
    51     }
    52     if(n==0) cout<<0<<endl;
    53     else if(n==1) cout<<1<<endl;
    54     else if(n==2) cout<<2<<endl;
    55     else{
    56         for(int i=c.length-1;i>=0;i--){
    57             cout<<c.v[i];
    58         }
    59         cout<<endl;
    60     }
    61     return 0;
    62 }

    三、进阶跳台阶

    博客对应课程的视频位置:7.3、进阶跳台阶
    https://www.fanrenyi.com/video/27/286

    1、问题描述

    有n级的台阶,你一开始在底部,
    每次可以向上迈最多n级台阶,
    问到达第n级台阶有多少种不同方式。


    题目位置:
    变态跳台阶_牛客网
    https://www.nowcoder.com/practice/22243d016f6b47f2a6928b4313c85387?tpId=13&&tqId=11162&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking

    2、分析及解答

     1 /*
     2 分析:
     3 
     4 f(1)=1
     5 f(2)=2
     6 f(3)=f(2)+f(1)+1=4
     7 f(4)=f(3)+f(2)+f(1)+1=8
     8 f(5)=f(4)+f(3)+f(2)+f(1)+1=16
     9 
    10 如果发现数字规律,可以直接
    11 f(n)=2^(n-1)
    12 
    13 如果没发现数字规律,可以用递推公式
    14 f(n)=f(n-1)+f(n-2)+...+f(1)+1
    15 
    16 */
    17 #include <iostream>
    18 using namespace std;
    19 int f[10000]={0};
    20 int main(){
    21     int n;
    22     cin>>n;
    23     f[1]=1;
    24     f[2]=2;
    25     //这层循环用来求f[i]
    26     for(int i=3;i<=n;i++){
    27         f[i]=1;
    28         for(int j=1;j<=i-1;j++){
    29             f[i]+=f[j];
    30         }
    31     }
    32     cout<<f[n]<<endl;
    33     return 0;
    34 }

    四、变态跳台阶

    博客对应课程的视频位置:7.4、变态跳台阶
    https://www.fanrenyi.com/video/27/287

    1、题目描述

    题目描述
    有N级的台阶,你一开始在底部,
    每次可以向上迈最多K级台阶(最少1级),
    问到达第N级台阶有多少种不同方式。
    输入格式
    两个正整数N,K。

    输出格式
    一个正整数,为不同方式数,由于答案可能很大,
    你需要输出ans mod 100003后的结果。

    输入输出样例
    输入
    5 2
    输出
    8

    数据范围:
    对于20%的数据,有N<=10, K<=3;
    对于40%的数据,有N<=1000;
    对于100%的数据,有N<=100000,K<=100。


    题目位置:
    P1192 台阶问题 - 洛谷
    https://www.luogu.com.cn/problem/P1192

    2、分析及解答

    分析:
    f(n)=f(n-1)+f(n-2)+...+f(n-k)

    n=5,k=2
    f(5)=f(4)+f(3)

    初始状态:
    f(1)=1

    前k项的值怎么确定
    这个时候,问题就变成有k级台阶,
    每次可以跳k步,问达到k级台阶有多少种跳法
    f(1)=1
    f(2)=2
    f(3)=f(2)+f(1)+1=4
    f(4)=f(3)+f(2)+f(1)+1=8
    f(5)=f(4)+f(3)+f(2)+f(1)+1=16

    算法思路:
    1、确定初始值(前k项)
    2、根据递推表达式来做递推

     1 #include <iostream>
     2 using namespace std;
     3 const int mod=100003;
     4 int f[100005]={0};
     5 int main(){
     6     int n,k;
     7     cin>>n;cin>>k;
     8     //1、确定初始值(前k项)
     9     f[1]=1;
    10     for(int i=2;i<=k;i++){
    11         f[i]=1;
    12         for(int j=1;j<=i-1;j++){
    13             f[i]=(f[i]+f[j])%mod;
    14         }
    15     }
    16     //2、根据递推表达式来做递推
    17     //f(n)=f(n-1)+f(n-2)+...+f(n-k)
    18     for(int i=k+1;i<=n;i++){
    19         for(int j=1;j<=k;j++){
    20             f[i]=(f[i]+f[i-j])%mod;
    21         }
    22     }
    23     cout<<f[n]<<endl;
    24     return 0;
    25 }



     
  • 相关阅读:
    夺命雷公狗—玩转SEO---50---让页面更好的被搜索引擎发现,自动推送篇
    夺命雷公狗—玩转SEO---49---让页面更好的被搜索引擎发现,主动推送篇
    夺命雷公狗—玩转SEO---48---让页面更好的被搜索引擎发现,外链篇
    夺命雷公狗—玩转SEO---47---让页面更好的被搜索引擎发现,网站地图篇
    夺命雷公狗—玩转SEO---46---浅谈搜索引擎
    夺命雷公狗—玩转SEO---45---浅入批量获得高频词
    夺命雷公狗—玩转SEO---44---外链群发原理
    夺命雷公狗—玩转SEO---43---外链提升网站权重
    夺命雷公狗—玩转SEO---42---快速交换友情链接
    夺命雷公狗—玩转SEO---41---H1标签的玩法
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/13067669.html
Copyright © 2020-2023  润新知