数据结构与算法——动态规划

例1:爬楼梯(easy)

爬楼梯汇总

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
 int climbStairs(int n) {
  vector<int>dp(n + 3, 0);
  dp[1] = 1;
  dp[2] = 2;
  for (int i = 3; i <= n; i++) {
   dp[i] = dp[i - 1] + dp[i - 2];
  }
  return dp[n];
 }
};
class Solution:
    def climb(self,n):
        dp=[0]*(n+1)
        dp[1]=1
        dp[2]=2
        for i in range(3,n+1):
            dp[i]=dp[i-1]+dp[i-2]
        return dp[n]

例2:打家劫舍(easy)

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
 int rob(vector<int>& nums) {
  if (nums.size() == 0) {
   return 0;
  }
  if (nums.size() == 1) {
   return nums[0];
  }
  vector<int> dp(nums.size(), 0);
  dp[0] = nums[0];
  dp[1] = max(nums[0], nums[1]);
  for (int i = 2; i < nums.size(); i++) {
   dp[i] = max(dp[i - 1], nums[i] + dp[i - 2]);
  }
  return dp[nums.size() - 1];
 }
};
class Solution:
    def rmb(self,nums):
        n=len(nums)
        if n==0:
            return 0
        if n==1:
            return nums[0]
        dp=[0]*(n+1)
        dp[0]=nums[0]
        dp[1]=max(nums[0],nums[1])
        for i in range(2,n):
            dp[i]=max(dp[i-2]+nums[i-1],dp[i-1])
        return dp[n-1]

例3:最大字段和(easy)

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
 int maxSubArray(vector<int>& nums) {
  vector<int>dp(nums.size(), 0);
  dp[0] = nums[0];
  int max_res = dp[0];
  for (int i = 1; i < nums.size(); i++) {
   dp[i] = max(dp[i - 1] + nums[i], nums[i]);
   if (dp[i] >= max_res) {
    max_res = dp[i];
   }
  }
  return max_res;
 }
};
class Solution:
    def max_sum(self,nums):
        n=len(nums)
        if n==1:
            return nums[0]
        if n==0:
            return 0
        dp=[0]*n
        dp[0]=nums[0]
        max_result=dp[0]
        for i in range(1,n):
            dp[i]=max(dp[i-1]+nums[i],nums[i])
            if dp[i]>max_result:
                max_result=dp[i]
        return max_result

例4:找零钱(medium)

在这里插入图片描述

class Solution {
public:
 int coinChange(std::vector<int>& coins, int amount) {
  std::vector<int> dp(amount + 1, -1);
  dp[0] = 0;
  for (int i = 1; i <= amount; i++) {
   for (int j = 0; j < coins.size(); j++) {
    if (i - coins[j] >= 0 && dp[i - coins[j]] != -1) {
     if (dp[i] == -1 || dp[i] > dp[i - coins[j]] + 1) {
      dp[i] = dp[i - coins[j]] + 1;
     }
    }
   }
  }
  return dp[amount];
 }
};

例5:三角形(medium)

在这里插入图片描述
在这里插入图片描述

class Solution {
public:
 int minimumTotal(vector<vector<int>>& triangle) {
  vector<vector<int>> dp(triangle);
  for (int i = dp.size() - 2; i >= 0; i--) {
   for (int j = 0; j < dp[i].size(); j++) {
    dp[i][j] = std::min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle[i][j];
   }
  }
  return dp[0][0];
 }
};
class Solution6:
    def minnums(self,triangle):
        dp=triangle
        m=len(triangle)
        if m==0:
            return 0
        if m==1:
            return dp[0][0]
        for i in range(m-2,-1,-1):
            for j in range(0,len(dp[i])):
                print(i,j)
                dp[i][j]=min(dp[i+1][j],dp[i+1][j+1])+triangle[i][j]
        return dp[0][0]

例6:最长上升子序列(medium,hard)

在这里插入图片描述

在这里插入图片描述

class Solution {
public:
 int lengthOfLIS(vector<int>& nums) {
  if (nums.size() == 0) {
   return 0;
  }
  vector<int>stack;
  stack.push_back(nums[0]);
  for (int i = 1; i < nums.size(); i++) {
   if (nums[i] > stack.back()) {
    stack.push_back(nums[i]);
   }
   else {
    for (int j = 0; j < stack.size(); j++) {
     if (stack[j] >= nums[i]) {
      stack[j] = nums[i];
      break;
     }
    }
   }
  }
  return stack.size();
 }
};
class Solution:
    def max_list(self,nums):
        if len(nums)==0:
            return 0
        temp_llist=[nums[0]]
        for i in range(1,len(nums)):
            id=len(temp_llist)
            if temp_llist[id-1] <nums[i]:
                temp_llist.append(nums[i])
            else:
                for j in range(id):
                    if temp_llist[j]>=nums[i]:
                        temp_llist[j]=nums[i]
                        break
        return len(temp_llist)

在这里插入图片描述

class Solution {
public:
 int lengthOfLIS(vector<int>& nums) {
  if (nums.size() == 0) {
   return 0;
  }
  vector<int>dp(nums.size(), 0);
  dp[0] = 1;
  int LIS = 1;
  for (int i = 1; i < nums.size(); i++) {
   dp[i] = 1;
   for (int j = 0; j < i; j++) {
    if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
     dp[i] = dp[j] + 1;
    }
   }
   if (LIS < dp[i]) {
    LIS = dp[i];
   }
  }
  return LIS;
 }
};

例7:最小路径和(medium)

在这里插入图片描述

class Solution {
public:
 int minPathSum(vector<vector<int>>& grid) {
  if (grid.size() == 0) {
   return 0;
  }
  int row = grid.size();
  int column = grid[0].size();
  vector<vector<int>>dp(grid);
  dp[0][0] = grid[0][0];
  for (int i = 1; i < column; i++) {
   dp[0][i] = grid[0][i] + dp[0][i - 1];
  }
  for (int i = 1; i < row; i++) {
   dp[i][0] = grid[i][0] + dp[i - 1][0];
   for (int j = 1; j < column; j++) {
    dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
   }
  }
  return dp[row - 1][column - 1];
 }
};
class Solution:
    def min_path(self,grid):
        dp=grid
        m,n=len(dp),len(dp[0])
        for i in range(1,m):
            dp[i][0]=dp[i-1][0]+grid[i][0]
        for j in range(1,n):
            dp[0][j]=dp[0][j-1]+grid[0][j]
        for i in range(1,m):
            for j in range(1,n):
                dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j]
        return dp[m-1][n-1]

例8:地牢游戏(hard)

在这里插入图片描述

在这里插入图片描述

class Solution {
public:
 int calculateMinimumHP(vector<vector<int>>& dungeon) {
  if (dungeon.size() == 0) {
   return 0;
  }
  vector<vector<int>> dp(dungeon);
  int row = dungeon.size();
  int column = dungeon[0].size();
  dp[row - 1][column - 1] = max(1, 1 - dungeon[row - 1][column - 1]);
  for (int i = column - 2; i >= 0; i--) {
   dp[row - 1][i] = max(1, dp[row - 1][i + 1] - dungeon[row - 1][i]);
  }
  for (int i = row - 2; i >= 0; i--) {
   dp[i][column - 1] = max(1, dp[i + 1][column - 1] - dungeon[i][column - 1]);
  }
  for (int i = row - 2; i >= 0; i--) {
   for (int j = column - 2; j >= 0; j--) {
    int dp_min = min(dp[i + 1][j], dp[i][j + 1]);
    dp[i][j] = max(1, dp_min - dungeon[i][j]);
   }
  }
  return dp[0][0];
 }
};
class Solution():
    def calculateMinimumHP(self,dungeon):
        if len(dungeon)==0:return 0
        dp=dungeon
        m,n=len(dungeon),len(dungeon[0])
        dp[m-1][n-1]=max(1,1-dungeon[m-1][n-1])
        for i in range(m-2,-1,-1):
            dp[i][n-1]=max(1,dp[i+1][n-1]-dungeon[i][n-1])
        for i in range(n-2,-1,-1):
            dp[m-1][i]=max(1,dp[m-1][i+1]-dungeon[m-1][i])
        for i in range(m-2,-1,-1):
            for j in range(n-2,-1,-1):
                dp_min=min(dp[i+1][j],dp[i][j+1])
                dp[i][j]=max(1,dp_min-dungeon[i][j])
        return dp[0][0]



if __name__=='__main__':
    s=Solution()
    res=s.calculateMinimumHP([[-2,-3,3],[-5,-10,1],[10,30,-5]])
    print(res)

例9:乘积最大子数组(medium)

在这里插入图片描述

class Solution(object):
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if nums is None:return 0
        dp=[[0 for _ in range(len(nums))] for _ in range(2)]
        dp[0][0],dp[1][0]=nums[0],nums[0]

        #[0]为正数最大,[1]负数为最小
        max_n=dp[0][0]

        for i in range(1,len(nums)):
            if nums[i]>=0:
                dp[0][i]=max(dp[0][i-1]*nums[i],nums[i])
                dp[1][i]=dp[1][i-1]*nums[i]
            else:
                dp[0][i]=dp[1][i-1]*nums[i]
                dp[1][i]=min(dp[0][i-1]*nums[i],nums[i],)
            max_n=max(dp[0][i],max_n)
        return max_n
class Solution(object):
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if nums is None:return 0
        dp=[[0 for _ in range(2)] for _ in range(2)]
        dp[0][1],dp[0][0],res=nums[0],nums[0],nums[0]
        for i in range(1,len(nums)):
            x,y=i%2,(i-1)%2
            dp[x][0]=max(dp[y][0]*nums[i],dp[y][1]*nums[i],nums[i])
            dp[x][1]=min(dp[y][0]*nums[i],dp[y][1]*nums[i],nums[i])
            res=max(res,dp[x][0])
        return res

例10:01 矩阵(medium)

在这里插入图片描述

class Solution:
    def updateMatrix(self,mat):
        m,n=len(mat),len(mat[0])
        dp=[[10**9]*n for _ in range(m)]
        for i in range(m):
            for j in range(n):
                if mat[i][j]==0:
                    dp[i][j]=0

        for i in range(m):
            for j in range(n):
                if i>=1:
                    dp[i][j]=min(dp[i][j],dp[i-1][j]+1)
                if j>=1:
                    dp[i][j]=min(dp[i][j],dp[i][j-1]+1)
        for i in range(m-1,-1,-1):
            for j in range(n-1,-1,-1):
                if i<m-1:
                    dp[i][j]=min(dp[i][j],dp[i+1][j]+1)
                if j<n-1:
                    dp[i][j]=min(dp[i][j],dp[i][j+1]+1)
        return dp
class Solution:
    def updateMatrix(self, matrix) :
        m, n = len(matrix), len(matrix[0])
        dp = [[0] * n for _ in range(m)]
        zeroes_pos = [(i, j) for i in range(m) for j in range(n) if matrix[i][j] == 0]
        # 将所有的 0 添加进初始队列中
        q = collections.deque(zeroes_pos)
        seen = set(zeroes_pos)

        # 广度优先搜索
        while q:
            i, j = q.popleft()
            for ni, nj in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
                if 0 <= ni < m and 0 <= nj < n and (ni, nj) not in seen:
                    dp[ni][nj] = dp[i][j] + 1
                    q.append((ni, nj))
                    seen.add((ni, nj))

        return dp
class Solution {
public:
	vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
		int n = mat.size(), m = mat[0].size();
		vector<vector<int>> dp(n, vector<int>(m, INT_MAX - 1));
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				if (!mat[i][j]) // 格点为0的位置初始dp状态为0
					dp[i][j] = 0;
		for (int i = 0; i < n; i++) // 左上到右下更新
			for (int j = 0; j < m; j++) {
				if (i >= 1) // 上移
					dp[i][j] = min(dp[i][j], dp[i - 1][j] + 1);
				if (j >= 1) // 左移
					dp[i][j] = min(dp[i][j], dp[i][j - 1] + 1);
			}
		for (int i = n - 1; i >= 0; i--) // 右下到左上更新
			for (int j = m - 1; j >= 0; j--) {
				if (i < n - 1) // 下移
					dp[i][j] = min(dp[i][j], dp[i + 1][j] + 1);
				if (j < m - 1) // 右移
					dp[i][j] = min(dp[i][j], dp[i][j + 1] + 1);
			}
		return dp;
	}
};
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小屋*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值