经典动态规划算法题(Java实现)


青蛙跳台阶

要求:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

思路:
如何跳上第n阶?
方法一:在第n-1阶向上跳1级
方法二:在第n-2阶向上跳2级
所以跳上第n阶的跳法等于 跳上第n-1阶的跳法 加上 跳上第n-2阶的跳法

代码:

   //迭代版
   public int JumpFloor(int target) {
        if (target==1||target==2) return target;
        int pre1 = 1;
        int pre2 = 2;
        int total = pre1+pre2;
        for(int i = 3;i<=target;i++){
            total = pre1+pre2;
            pre1 = pre2;
            pre2 = total;
        }
        return total;
    }
    
//递归版(时间复杂度2的阶乘太高)
public int JumpFloor(int target) {
        if(target==1||target==2) return target;
        return JumpFloor(target-1)+JumpFloor(target-2);
    }

数列中求出最大取值

来源:https://www.bilibili.com/video/av18512769/?spm_id_from=333.788.videocard.0

要求:
一个数列,可以取任意多的数,但取的数不能相邻,最大能取到多大

思路:
每个数有取和不取的两种选择,选择能取得最大值的那种
opt(i)代表0-i这些数能取到的最大的值
如果取当前i这个数,前面那个数就不能取,那么最大值为opt(i-2)+arr[i]
如果不取这个数,最大值为opt(i-1)
两种选择取最大值

代码:

//递归版
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        int[] weights = {1,2,4,1,7,8,3};
        System.out.println(get(weights.length-1,weights));

    }

   static int get(int i,int[] arr){
        if (i==0){
            return arr[0];
        }
        if (i==1){
            return Math.max(arr[0],arr[1]);
        }
        return Math.max(arr[i]+get(i-2,arr),get(i-1,arr));
    }
}
//非递归
 public static void main(String[] args){
        int totalWeight = 100;
        int[] weights = {4,1,1,9,1};
        int[] opt = new int[weights.length];
        opt[0] = weights[0];
        opt[1] = Math.max(weights[0],weights[1]);
        for(int i = 2;i<opt.length;i++){
            opt[i] = Math.max(opt[i-2]+weights[i],opt[i-1]);
        }
        System.out.println(opt[weights.length-1]);
    }

是否存在几个数恰好等于某个数

来源:https://www.bilibili.com/video/av18512769/?spm_id_from=333.788.videocard.0

要求:
一个数列,是否存在几个数恰好等于某个数
思路:
每个数有取和不取的两种选择
opt(i,sum)代表0-i个数中是否存在几个数恰好等于某个数
如果取当前i这个数,结果为opt(i-1,sum-arr[i)
如果不取这个数,结果为opt(i-1,sum)
两种选择其中一个结果为true就是true

代码:

import java.util.*;
public class Main {

    public static void main(String[] args){
        int[] arr = {2,12,54,6,8,2};
        int sum = 60;
        System.out.println(test(arr.length-1,sum,arr));
    }

    static boolean test(int i,int sum,int[] arr){
        if (sum==0){
            return true;
        }
        if (i==0) {
            return arr[i] == sum;
        }
        if (arr[i]>sum){
            return test(i-1,sum,arr);
        }
        return test(i-1,sum-arr[i],arr)||test(i-1,sum,arr);
    }
}
  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值