[前端算法]动态规划

最优子结构,重叠子问题

爬楼梯

递归+记忆化搜索

自顶向下

var climbStairs = function(n) {
    let map=[]
   function dfs(n)
   {
    if(n<=2) return n
  if(map[n] == undefined) map[n]=dfs(n-1)+dfs(n-2)

    return map[n]
   }
   return dfs(n)
};

动态规划

自底向上

var climbStairs = function(n) {
    let dp=[]
    dp[1]=1;
    dp[2]=2;

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

    return dp[n]
};

最值问题

function coinChange(coins, amount) {

  let dp = [0];

  for (let i = 1; i <= amount; i++) {

    dp[i] = Infinity;

    for (let j = 0; j < coins.length; j++) {

      if (i >= coins[j]) {

        dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);

      }

    }

  }

  if (dp[amount] === Infinity) {

    return -1;

  }

  return dp[amount];

}

01背包问题

function knapsack(n, c, w, value) {

  //dp[i][j]表示前i个物品,背包容量为j时的最大价值

  //dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+value[i])

  let dp = [];

  //初始化

  for (let i = 0; i <= n; i++) {

    dp[i] = [];

    for (let j = 0; j <= c; j++) {

      dp[i][j] = 0;

    }

  }

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

    for (let j = 1; j <= c; j++) {

      if (j >= w[i]) {

        dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - w[i]] + value[i]);

      } else {

        dp[i][j] = dp[i - 1][j];

      }

    }

  }

  return dp[n][c];

}

最长上升子序列问题

300. 最长递增子序列 - 力扣(LeetCode)

子序列,在原有序列的基础上,删除0个或多个数,其他数的顺序保持不变得到的结果

function lengthOfLIS(nums) {

  //dp[i]表示以nums[i]结尾的最长上升子序列的长度

  //初始化,每个索引位都存在一个以自己为结尾的子序列,长度为1

  let dp = new Array(nums.length).fill(1);

  let max = 1;

  for (let i = 1; i < nums.length; i++) {

    for (let j = 0; j < i; j++) {

      if (nums[i] > nums[j]) {

        dp[i] = Math.max(dp[i], dp[j] + 1);

      }

    }

    if (max < dp[i]) {

      max = dp[i];

    }

  }

  return max;

}

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