算法与数据结构-动态规划 讲解与java代码实现

1. 从暴力搜索到记忆搜索,再到动态规划

算法与数据结构-动态规划 讲解与java代码实现_第1张图片算法与数据结构-动态规划 讲解与java代码实现_第2张图片算法与数据结构-动态规划 讲解与java代码实现_第3张图片算法与数据结构-动态规划 讲解与java代码实现_第4张图片算法与数据结构-动态规划 讲解与java代码实现_第5张图片算法与数据结构-动态规划 讲解与java代码实现_第6张图片

2. 找零问题

有数组penny,penny中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim(小于等于1000)代表要找的钱数,求换钱有多少种方法。
给定数组penny及它的大小(小于等于50),同时给定一个整数aim,请返回有多少种方法可以凑成aim。
测试样例:
[1,2,4],3,3
返回:2

import java.util.*;
//动态规划方法求解给定数额求找零方法的总数 是用空间换时间 时间复杂度为O(n*aim) 下一层方法总是枚举上一层的方法
public class Exchange {
    public int countWays(int[] penny, int n, int aim) {
        int[] dp=new int[aim+1];
        dp[0]=1;//得到0值的方法对任何面值的组合来说都只有一种
        for(int i=0;ifor(int j=penny[i];j<=aim;j++){
                dp[j]+=dp[j-penny[i]];
            }
        }
        return dp[aim];
    }
}

3. 台阶问题

有n级台阶,一个人每次上一级或者两级,问有多少种走完n级台阶的方法。为了防止溢出,请将结果Mod 1000000007
给定一个正整数int n,请返回一个数,代表上楼的方式数。保证n小于等于100000。
测试样例:
1
返回:1

import java.util.*;
//每次只能走1或者2步,求走完n个台阶的方法数 倒推使用f(i)=f(i-1)+f(i-2)的方法
public class GoUpstairs {
    public int countWays(int n) {
        /*if(n<1){
            return 0;
        }
        if(n==1||n==2){
            return n;
        }

        return (count(n-1)+count(n-2))%1000000007;
       */ //为什么数组越界?
        int[] res=new int[300030];//大小如何确定的?
        res[0]=1;
        for(int i=1;i<=n;i++){
            res[i]=((i>=1?res[i-1]:0)+(i>=2?res[i-2]:0))%1000000007;
        }
        return res[n];
    }

}

4. 格子最短路径问题

算法与数据结构-动态规划 讲解与java代码实现_第7张图片

import java.util.*;
//格子最短路径求解
public class MinimumPath {
    public int getMin(int[][] map, int n, int m) {
        int[][] dp=new int[n][m];
        dp[0][0]=map[0][0];
        for(int i=0;ifor(int j=0;jif(i==0&&j==0){
                    continue;
                }
                dp[i][j]=map[i][j]+Math.min((i>=1?dp[i-1][j]:dp[0][j-1]),(j>=1?dp[i][j-1]:dp[i-1][0]));
            }
        }

        return dp[n-1][m-1];
    }
}

5. LIS最大递增子序列

算法与数据结构-动态规划 讲解与java代码实现_第8张图片

import java.util.*;
//数组最长上升自序列问题
public class LongestIncreasingSubsequence {
    public int getLIS(int[] A, int n) {
        int[] dp=new int[n];
        int totalMax=0;
        for(int i=0;iint max=0;
            for(int j=i-1;j>=0;j--){
               if(dp[j]>max&&A[j]1+max;
            if(dp[i]>totalMax){
                totalMax=dp[i];
            }
        }
        return totalMax;
    }
}

6. LCS公共最长子序列

算法与数据结构-动态规划 讲解与java代码实现_第9张图片

import java.util.*;
//公共最长子序列求解
public class LCS {
    public int findLCS(String A, int n, String B, int m) {
       int[][] dp=new int[n][m];
        //处理第0行,只要B[i]==A[0] 那么B[i+1,...m]都为1
        boolean rFlag=false;
         for(int j=0;jif(A.charAt(0)==B.charAt(j)||rFlag==true){
                 dp[0][j]=1;
                 rFlag=true;
            }
         }

        boolean cFlag=false;
        for(int i=0;iif(B.charAt(0)==A.charAt(i)||cFlag){
                dp[i][0]=1;
                cFlag=true;
            }
        }

        for(int i=1;ifor(int j=1;jif(A.charAt(i)==B.charAt(j)){
                    dp[i][j]=dp[i-1][j-1]+1;
                }else{
                    dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }

        return dp[n-1][m-1];
    }
}

7. 背包问题

算法与数据结构-动态规划 讲解与java代码实现_第10张图片

import java.util.*;
//背包问题
public class Backpack {
    public int maxValue(int[] w, int[] v, int n, int cap) {
        int[][] dp=new int[n][cap+1];
        //处理第一个物品的价值
        for(int column=0;column<=cap;column++){
            if(column>=w[0]){
                dp[0][column]=v[0];
            }
        }

        for(int i=1;ifor(int j=1;j<=cap;j++){
                int a=dp[i-1][j];
                int b=0;
                if((j-w[i])>=0){
                   b=dp[i-1][j-w[i]]+v[i];
                }
                dp[i][j]=Math.max(a,b);
            }
        }

        return dp[n-1][cap];
    }
}

8. 编辑字符串最小代码问题

算法与数据结构-动态规划 讲解与java代码实现_第11张图片
算法与数据结构-动态规划 讲解与java代码实现_第12张图片

import java.util.*;
//最优编辑问题
public class MinCost {
    public int findMinCost(String A, int n, String B, int m, int c0, int c1, int c2) {
        int[][] dp=new int[n+1][m+1];

        //处理第一列,即删除0-i-1的字符变到空串的代价,为c1*i
        for(int i=1;i<=n;i++){
            dp[i][0]=c1*i;
        }

        //处理第一行,即增加0-j-1个字符编导B串的代价,为c0*j
        for(int j=0;j<=m;j++){
            dp[0][j]=c0*j;
        }

        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                int a=dp[i-1][j]+c1;
                int b=dp[i][j-1]+c0;
                int c=(A.charAt(i-1)==B.charAt(j-1)?dp[i-1][j-1]:(dp[i-1][j-1]+c2));

                dp[i][j]=Math.min(Math.min(a,b),c);
            }
        }
        return dp[n][m];
    }
}

9. JAVA

*     java要获取字符串中的单个字符 S.charAt(index),不能使用S[index]方式
*     Math.min(a,b)只接受两个数,如果要比较三个数,可以采用Math.min(Math.min(a1,a2),a3)

你可能感兴趣的:(算法,java,动态规划,算法)