zoukankan      html  css  js  c++  java
  • 20191026-跳台阶

    • 斐波那契数列 - 矩阵算法(O(lgn)) - 待补充
    • 跳台阶 - 经典问题
      • 递归 - basic解法,浪费栈空间
      • 动态规划 - 常规解法,转移方程可以有很多变化
      • 打表 - 按照转移方程提前计算
      • 注意:台阶数很多的时候,需要手写大数加法
    • 变态跳台阶/观察法
    • 跳石板/动态规划
    • 爬楼梯/大数跳台阶
    • 爬楼梯2/大数加法

    变态跳台阶

    一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法 (2^{n-1})

    思路

    • 思路1

      • 青蛙一次可以跳1~n之间的台阶数,考虑如下情况
        • 青蛙一次跳n阶,则1~n-1的所有台阶均不经过
        • 青蛙第一次跳n-1阶,第二次跳1阶,等价于仅选中n-1阶
      • 所以,观察可得,每种跳台阶方案都对应了1~n-1中的唯一一组选择
        • 1~n-1共n-1级台阶,每级台阶都有选or不选两种情况
        • 总的跳法数目为(2^{n-1})
    • 思路2

      • (f(n-1)=2^{n-2}) 数学归纳法
      • (f(n)=1+f(n-1)+f(n-2)+f(n-3)+...+f(2)+f(1))
      • (f(n)=2^{n-1})

    跳石板

    小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3.......
    这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
    例如:
    N = 4,M = 24:
    4->6->8->12->18->24
    于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板

    思路

    状态转移

    (steps[i+j]=min(steps[i]+1,steps[i+j]))

    (steps[i+i/j]=min(steps[i]+1,steps[i+i/j]))

    注意这里对约数的处理很巧妙,j from 2 to i^(1/2)

    代码

    #include<iostream>
    #include<climits> //INT_MAX,INT_MIN等
    #include<cmath> //min,max等函数
    #include<vector>
    using namespace std;
    
    int main(){
        int N,M;
        while(cin>>N>>M){
            vector<int> steps(M+1,INT_MAX);
            steps[N]=0;
            for(int i=N;i<=M;i++){
                if(steps[i]==INT_MAX)
                    continue;
                //快速计算i的约数
                for(int j=2;(j*j)<=i;j++){
                    if(i%j==0){
                        if(i+j<=M){
                            steps[i+j]=min(steps[i]+1,steps[i+j]);
                        }
                        if(i+i/j<=M){
                            steps[i+i/j]=min(steps[i]+1,steps[i+i/j]);
                        }
                    }
                }
            }
            if(steps[M]==INT_MAX){
                steps[M]=-1;
            }
            cout<<steps[M]<<endl;
        }
    }
    

    爬楼梯

    题目描述

    在你面前有一个n阶的楼梯,你一步只能上1阶或2阶。
    请问计算出你可以采用多少种不同的方式爬完这个楼梯。

    输入描述:

    一个正整数n(n<=100),表示这个楼梯一共有多少阶
    

    输出描述:

    一个正整数,表示有多少种不同的方式爬完这个楼梯
    

    思路

    不愧是校招题目,大坑在数据范围,unsigned long long不够用,需要手写大数加法

    代码

    #include<iostream>
    using namespace std;
    
    int main(){
        int n;
        cin>>n;
        int num[103][30]={0};//二维数组的初始化,int数组进行大数加法
        num[1][29]=1;
        num[2][29]=2;
        for(int i=3;i<=100;i++){
            //从低位向高位计算
            int carry=0;//进位初始设置为0
            for(int j=29;j>=0;j--){
                num[i][j]=(num[i-1][j]+num[i-2][j]+carry)%10;
                carry=(num[i-1][j]+num[i-2][j]+carry)/10;
            }
        }
        int j=0;
        while(num[n][j]==0)
            j++;
        for(int i=j;i<30;i++)
            cout<<num[n][i];
        cout<<endl;
    }
    

    爬楼梯2

    题目描述

    在你面前有一个n阶的楼梯(n>=100且n<500),你一步只能上1阶或3阶。
    请问计算出你可以采用多少种不同的方式爬完这个楼梯(到最后一层为爬完)。

    输入描述:

    一个正整数,表示这个楼梯一共有多少阶
    

    输出描述:

    一个正整数,表示有多少种不同的方式爬完这个楼梯
    

    代码

    #include<iostream>
    
    using namespace std;
    
    int len=99;
    
    int num[501][100];//这里大数的位数会很高,用len+1表示
    
    int main(){
        num[1][len]=1;
        num[2][len]=1;
        num[3][len]=2;
        for(int i=4;i<500;i++){
            int carry=0;
            for(int j=len;j>=0;j--){
                num[i][j]=(num[i-1][j]+num[i-3][j]+carry)%10;
                carry=(num[i-1][j]+num[i-3][j]+carry)/10;
            }
        }
        int n;
        cin>>n;
        int j=0;
        while(num[n][j]==0)
            j++;
        for(;j<=len;j++){
            cout<<num[n][j];
        }
        cout<<endl;
    }
    
  • 相关阅读:
    windows的磁盘操作之七——获取当前所有的物理磁盘号 加备注
    ajax后台处理响应(java)
    单词前后位置颠倒,大小写颠倒
    电话面试总结(问的很细).md
    HTTP协议
    Java并发——结合CountDownLatch源码、Semaphore源码及ReentrantLock源码来看AQS原理
    Java并发——ThreadPoolExecutor线程池解析及Executor创建线程常见四种方式
    TCP协议三次握手和四次握手
    OSI参考模型总结
    Java并发——CAS
  • 原文地址:https://www.cnblogs.com/cbw052/p/11745662.html
Copyright © 2011-2022 走看看