Dynamic programming algorithm java code implementation

Two examples, the use of dynamic programming algorithm to solve the
first example is LeetCode topic:

17.16 face questions:

Masseur massage therapist will receive a steady stream of known reservation request, the reservation can be selected for each connection or not connected. Between each reservation service have time to rest, so she could not accept neighboring appointment. Given a sequence of reservation request, the reservation for the massage therapist to find the optimal set (longest total reservation), and returns the total number of minutes.
Recursive method:


public static int rec_opt(int []arr,int i){
    //递归终止的条件,意味着如果只能选第一个,那么最好的方法就是arr[0]
    if(i==0)
        return arr[0];
    //处理特殊情况,因为题目要求间隔选择
    else if(i==1)
        return Math.max(arr[0],arr[1]);
    else{
        int a = rec_opt(arr,i-2) + arr[i];  //对于每一个顾客无非两种情况,选或者不选,如果选的话,就是,i-2个的最优解加上当前的value
        int b = rec_opt(arr,i-1);           //如果不选,那么就只能使用上一个的最优解
        return Math.max(a,b);                 //最后比较两种情况,得出当前情况的最优解
    }
}

Non-recursive method:

public static int dp_opt(int []arr){
        int len =arr.length;
        if(len == 0) return 0;
        if(len == 1) return arr[0];
        int []opt = new int[len];
        opt[0]=arr[0];
        opt[1]=Math.max(arr[1],arr[0]);
        for(int i=2;i<len;i++){
            int a = opt[i-2] + arr[i];  //对于每一个顾客无非两种情况,选或者不选,如果选的话,就是,i-2个的最优解加上当前的value
            int b = opt[i-1];           //如果不选,那么就只能使用上一个的最优解
            opt[i] = Math.max(a,b);     //最后比较两种情况,得出当前情况的最优解
        }
        return opt[len-1];
    }
A second example:

Given an array of a number and, if there are one or more digital array can be obtained by adding the number, the return true, not false (ps returns: do not consider an array with a negative number is given and a negative number)
recursive method:

public static boolean rec_subset(int []nums,int i,int s){  //传进来的是len-1表示,从后往前找可能的情况
   if(s==0) return true;   //如果s等于0表示已经找到了需要的数字
   else if(i==0) return nums[0]==s;    //如果找到了最后一个数字,也就是数组中的第一个数字,那么如果这个数与s不等,也就说明,该种情况不可能
   else if(nums[i]>s) return rec_subset(nums,i-1,s);   //如果当前数字大于s也就没必要找这个分支,直接进入不用该数字的分支
   else{
       boolean a = rec_subset(nums,i-1,s-nums[i]); //对于每一个数字无非有两种情况,选他和不选他,选他,就递归调用,求之前的数组中有无数字相加得到s-nums[i]
       boolean b = rec_subset(nums,i-1,s);            //不选:求之前的数组,有无数字相加得到s
       return a||b;
   }
}

Non-recursive method:

public static boolean dp_subset(int []nums,int S){
    if(S<=0) return false;    //暂且不考虑小于等于零的情况
    int len = nums.length;
    boolean [][]subset = new boolean[len][S+1];     //新建二维数组保存子问题结果
    for(int i=0;i<S+1;i++) subset[0][i]=false;      //初始化第一行
    for(int i=0;i<len;i++) subset[i][0]=true;   //初始化第一列
    subset[0][nums[0]] = true;
    for(int i=1;i<len;i++)
        for(int s=1;s<S+1;s++)
            if(nums[i]>s)       //如果当前数字大于s也就没必要找这个分支,直接进入不用该数字的分支
                subset[i][s] = subset[i-1][s];
            else
                subset[i][s] = subset[i-1][s-nums[i]] || subset[i-1][s];    //两种情况的判断
    return subset[len-1][S];
}

Also recommend learning dynamic programming instructional video of the first month of lanterns point b station.

Guess you like

Origin www.cnblogs.com/yue1234/p/12568545.html