动态规划(一)

动态规划精讲

动态规划(一)

参考了https://blog.youkuaiyun.com/u013565099/article/details/76610875
收获颇多
动态规划问题关键是找出状态和状态转移条件,但是我还是不熟练qwq

斐波拉契数列
/**
 * @Author: TJW
 * @Description:
 * @Date: 2018/12/7
 */
public class DP_fib {

    public static void main(String[] args) {
        fib_dp();
    }

    public static void fib_dp(){
        // fib1
        //space 30
        int[] result = new int[30];
        for(int i=0;i<30;i++){
            result[i] = -1;
        }
        result[0] = 1;
        result[1] = 1;
        //print(result);
        System.out.println("fib1:"+fib1(10,result));
        //print(result);
        //System.out.println("fib1:"+fib1(5,result));
        //print(result);

        // fib2
        System.out.println("fib2:"+fib2(10));

        // fib3 uses less space than that fib2 uses
        System.out.println("fib3:"+fib3(10));
    }

    // fib(0-29) top-down, save result
    public static int fib1(int n,int[] result){
        if(result[n]!=-1){
            return result[n];
        }else{
            result[n] = fib1(n-1,result)+fib1(n-2,result);
            return result[n];
        }
    }

    // fib bottom-up
    public static int fib2(int n){
        if(n<=1){
            return 1;
        }else{
            int temp[] = new int[n+1];
            temp[0] = 1;
            temp[1] = 1;
            for(int i=2;i<n+1;i++){
                temp[i]=temp[i-1]+temp[i-2];
            }
            return temp[n];
        }
    }

    public static int fib3(int n){
        if(n<=1){
            return 1;
        }else{
            int temp0 = 1;
            int temp1 = 1;
            int temp2 = 0;
            for(int i=2;i<n+1;i++){
                temp2 = temp0+temp1;
                temp0 = temp1;
                temp1 = temp2;
            }
            return temp2;
        }
    }
    public static void print(int[] result){
        for(int i=0;i<result.length;i++){
            System.out.print(result[i]+" ");
        }
        System.out.println();
    }
}

硬币方案

思路:先赋值为只能有1的情况(最多硬币数情况),然后根据可以使用的硬币,将d[i]的指改为d[j+x]=min(d[i],d[j]+1),其中j+x=i,x表示硬币的面额,j表示之前总值为j的情况。

import java.util.Scanner;

/**
 * @Author: TJW
 * @Description:
 * @Date: 2018/12/7
 */
public class DP_coin {

    public static void main(String[] args) {

        int coins[] = new int[]{1,3,5};
        System.out.println("kinds of coins: 1 3 5");
        Scanner scanner = new Scanner(System.in);
        System.out.println("enter your want num:");
        int want = scanner.nextInt();
        scanner.close();

        int[] minSet = new int[100];
        //都使用1的情况
        for(int i=0;i<100;i++){
            minSet[i] = i;
        }

        for(int i=0;i<100;i++){
            for(int j=0;j<3;j++){
                if(coins[j]<i && minSet[i-coins[j]]+1<minSet[i]){
                    minSet[i] = minSet[i-coins[j]]+1;
                }
            }
        }

        System.out.println(minSet[want]);

    }

}

最大非减子序列

思路:d[i]是第i个数前可以组成的最大非减子序列,其可以表示为第j个数(小于第i个数)的最大非减子序列+1(如果比现存的值要大)。

/**
 * @Author: TJW
 * @Description:
 * @Date: 2018/12/7
 */
public class DP_LIS {

    public static void main(String[] args) {
        int[] list = new int[]{5,3,4,8,6,7};
        int[] maxLength = new int[list.length];
        int len=1;
        for(int i=0;i<list.length;i++){
            maxLength[i] = 1;
            for(int j=0;j<i;j++){
                //the most important step
                if(list[j]<list[i] && maxLength[j]+1>maxLength[i]){
                    maxLength[i] = maxLength[j] + 1;
                }
                if(maxLength[i]>len){
                    len = maxLength[i];
                }
            }
        }
        for(int i=0;i<maxLength.length;i++){
            System.out.println(i+1+":"+maxLength[i]);
        }
        System.out.println(len);
    }
}

最多苹果数(从左上角开始,只能向下或向右)

思路:从上到下,依次保存最大苹果数。d[i][j]的数量由上或左所含的最大苹果数量决定。

import java.util.Scanner;

/**
 * @Author: TJW
 * @Description:
 * @Date: 2018/12/7
 */
public class DP_path {

   /*max path, only turn down or turn left
   1
   2 3
   4 5 2

   1
   3 6
   7 12 14
    */
   public static void main(String[] args) {
       Scanner scanner = new Scanner(System.in);
       int[][] matrix = new int[][]{{1,0,0},{2,3,0},{4,5,2}};
       int[][] result = new int[3][3];
       for(int i=0;i<3;i++){
           for(int j=0;j<=i;j++){
               if(j-1>=0 && i-1>=0){
               	  //the most important step
                   int max_added = Math.max(result[i][j-1],result[i-1][j]);
                   result[i][j] = max_added+matrix[i][j];
               }else if(i-1<0){
                   result[i][j] = matrix[i][j];
               }else if(j-1<0){
                   result[i][j] = matrix[i][j]+result[i-1][j];
               }
           }
       }

       for(int i=0;i<3;i++){
           for(int j=0;j<=i;j++){
               System.out.print(result[i][j]+" ");
           }
           System.out.println();
       }
   }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值