动态规划算法(dynamic planning)

在这里插入图片描述
求数组中是否存在某几个数相加等于s?
这里我使用的是Java实现:

使用递归实现

public class Test1 {
    public static void main(String[] args) {
        int[] arr={3,34,4,12,5,2,0};
        System.out.println(dp_subset(arr,9));
        System.out.println(dp_subset(arr,10));
        System.out.println(dp_subset(arr,11));
        System.out.println(dp_subset(arr,13));
    }

    /**
     *使用递归实现
     * @param arr 所需数组
     * @param i   数组的下标
     * @param s    还需要的数
     * @return
     */
    public static Boolean opt(int[] arr,int i,int s) {
        if (s == 0) {
            //如果当前s已经为0 那么直接返回true
            return true;
        } else if (i==0) {
            //如果数组下标已经到0了,就判断此时数组的值是否等于s,若是,则返回true
            return arr[i]==s;
        } else if (arr[i] > s) {
            //如果当前数组大于s,那么就直接进入上一层判断
            return  opt(arr, i - 1, s);
        } else {
            //取当前数组的值
            Boolean A = opt(arr, i - 1, s - arr[i]);
            //不取当前数组的值
            Boolean B = opt(arr, i - 1, s);
            if(A || B){
                //如果A 或 B中有一个为true 则返回true
                return true;
            }
        }
        return false;
    }

   

使用动态规划实现

/**
     * 使用动态规划实现
     * @param arr
     * @param S
     * @return
     */
    public static boolean dp_subset(int[] arr, int S) {
        //定义一个二维数组,行代表数组的下标
        // 列代表从0开始的S
        boolean[][] subset = new boolean[arr.length][S+1];


        for(int i = 0;i<S+1;i++) {
            /**
             * 将第一行所有值都先设置为false
             */
            subset[0][i] = false;
        }
        for(int i = 0;i<arr.length;i++) {
            /**
             * 当s=0时,每一行的第一个值都可取
             * 将每一行的第一个值都设置为true
             */
            subset[i][0] = true;
        }
//        if(S>=arr[0]) {
            subset[0][arr[0]]=true;
//        }
        for(int i = 1;i<arr.length;i++) {
            for(int s=1;s<S+1;s++) {
                //遍历二维数组
                if(arr[i] >s){
                    /**
                     * 若当前数组值大于所需s
                     * 则直接进入下一层判断
                     */
                    subset[i][s] = subset[i-1][s];
                }
                else {
                    /**
                     * 是否取当前数组的值
                     * a代表取值
                     * b代表不取,直接进入下一层判断
                     */
                    boolean a = subset[i-1][s-arr[i]];
                    boolean b = subset[i-1][s];
                    subset[i][s] = a||b;
                }
            }
        }
        return subset[arr.length-1][S];
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值