0
点赞
收藏
分享

微信扫一扫

动态规划初级篇(下)

精进的医生 2022-03-30 阅读 74

目录

        ⌛序列型动态规划

        👇Example 1(房屋染色)

        👇Example 2(最少费用的爬台阶方法)

        👇Example 3(俄罗斯套娃信封)

        👇Example 4(完美平方)

        👇Example 5(买卖股票的最佳时机)

        🎈博弈型动态规划

        👇Example 6 (硬币排成线)


⌛序列型动态规划

👇Example 1(房屋染色)

public class Solution {
    public int minCost(int[][] costs) {
        int n = costs.length;

        int[][] dp = new int[n+1][3];

        dp[0][0]=0;
        dp[0][1]=0;
        dp[0][2]=0;

        for(int i=1; i<=n; i++){
            for(int j=0;j<3; j++){
                dp[i][j] = Integer.MAX_VALUE;
               
                for(int k=0;k<3;k++){
                    //相邻不能撞色
                    if(j==k){
                        continue;
                    } 
                    //选择染色的最小花费
                    dp[i][j]=Math.min(dp[i][j],dp[i-1][k]+costs[i-1][j]);
                }
                
            }
        }
       //选出最小值
       int ret = dp[n][0];
       if(ret>dp[n][1]){
           ret = dp[n][1]; 
       }

       if(ret >dp[n][2]){
           ret = dp[n][2];
       }

       return ret;
    }
}

👇Example 2(最少费用的爬台阶方法)

public class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        
        if(n == 0 || cost == null){
            return 0;
        }

        int[] dp = new int[n+1];
        
        //初始化
        dp[0] = 0;
        dp[1] = 0;

        for(int i=2; i<=n;i++){
            
            dp[i] = Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);

        }
        return dp[n];
    }
}

👇Example 3(俄罗斯套娃信封)

public class Solution {
    public int maxEnvelopes(int[][] envelopes) {

        int n = envelopes.length;
        if(n == 0 || envelopes == null){
            return 0;
        }

        //排序
        Arrays.sort(envelopes,new Comparator<int[]>(){
            public int compare(int[] a, int[] b){
                if(a[0] == b[0]){
                    return a[1]-b[1];
                }else{
                    return a[0]-b[0];
                }
            }
        });

        int[] dp =new int[n+1];
        dp[0] =0;
        int ret = 0;//记录能装最大的信封数

        for(int i=1; i<=n; i++){
            dp[i] = 1;

            for(int j=1;j<i; j++){
                if(envelopes[i-1][0]>envelopes[j-1][0] 
                    && envelopes[i-1][1]>envelopes[j-1][1]){
                    dp[i] = Math.max(dp[j]+1,dp[i]);
                }
            }
            ret = Math.max(dp[i], ret);
        }
        return ret;
    }      
}

👇Example 4(完美平方)

public class Solution {
    public int numSquares(int n) {

        int x = (int)Math.sqrt(n);

        if(x*x == n){
            return 1;
        }
        int[] dp = new int[n+1];
        dp[0] = 0;
  
        for(int i=1; i<=n; i++){
            dp[i] = dp[i-1]+1;//最差的情况在上一次情况下+1
            for(int j=1; j*j<=i; j++){
                dp[i] =Math.min(dp[i-j*j]+1,dp[i]);
            }
        }
        return dp[n];
    }
}

👇Example 5(买卖股票的最佳时机)

public class Solution {
    public int maxProfit(int[] prices) {

        int n = prices.length;
  
       int[][] dp = new int[n+1][5+1];
       //初始化
       dp[0][1] = 0;
       for(int i=2; i<6; i++){
           dp[0][i] =Integer.MIN_VALUE;
       }

       for(int i=1; i<=n; i++){

           //处于1,3,5阶段
           for(int j=1; j<=5; j+=2){
                dp[i][j] = dp[i-1][j];
               if(i>1 && j>1 && dp[i-1][j-1] != Integer.MIN_VALUE)
               dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-1]+prices[i-1]-prices[i-2]);
           }

           //处于1,4阶段
           for(int j=2; j<5; j+=2){
               dp[i][j] = dp[i-1][j-1];
               if( i>1 &&dp[i-1][j] != Integer.MIN_VALUE){
                   dp[i][j] = Math.max(dp[i][j], dp[i-1][j]+prices[i-1]-prices[i-2]);
               }
               if(j>1 && i>1 && dp[i-1][j-2] != Integer.MIN_VALUE){
                    dp[i][j] = Math.max(dp[i-1][j-2]+prices[i-1]-prices[i-2],dp[i][j]);
               }
              
           }
       }
       int ret = Math.max(Math.max(dp[n][1], dp[n][3]), dp[n][5]);

       return ret;
    }
}

🎈博弈型动态规划

👇Example 6 (硬币排成线)

public class Solution {
    /**
     * @param n: An integer
     * @return: A boolean which equals to true if the first player will win
     */
    public boolean firstWillWin(int n) {

       
        if(n == 0){
            return false;
        }

        if(n<=2){
            return true;
        }

        boolean[] dp = new boolean[n+1];
        //初始化
        dp[0] = false;
        dp[1] = true;
        dp[2] = true;

        for(int i=3; i<=n; i++){
           dp[i] = dp[i-1] == false || dp[i-2] == false;
        }

        return dp[n];
    }
}
举报

相关推荐

0 条评论