首页 > 编程语言 >数据结构与算法学习——动态规划

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

时间:2024-05-21 16:54:54浏览次数:36  
标签:cnt dp4 dp3 int res 算法 数据结构 dp 动态

动态规划

动态规划(英语:Dynamic programming,简称DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
动态规划常常适用于有重叠子问题[1]和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。
动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再根据子问题的解以得出原问题的解。
通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量:一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。

题目

PS:下列题目均来自leetcode中灵神题单

入门

1.1 爬楼梯

70. 爬楼梯

public class Solution {
    public int climbStairs(int n) {
        int[] d = new int[n + 1];
        d[0] = d[1] = 1;
        for (int i = 2; i <= n; i++) {
            d[i] = d[i - 1] + d[i - 2];
        }
        return d[n];
    }
}

746. 使用最小花费爬楼梯

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n=cost.length;
        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];

    }
}

2266. 统计打字方案数

"""
思路为构建dp,dp[i]为countTexts第i个数字结尾的所有可能性
那么显然dp[i]=dp[i-1]+dp[-2]+dp[i-3]
和爬楼梯类似,从dp[i-3]一次跳到dp[i],dp[i-2]一次跳到dp[i]这样
再使用乘法原理分割连续相同的字符串
我个考虑的时候
1. 忘记了乘法原理
2. 我考虑的时候想的是dp[i]=dp[i-1]+1+dp[i-2]+1+dp[i-3]+1想的很抽象,不知道为什么我在考虑的时候没有正确理解到dp[i]=dp[i-1]+...里面的dp[i-1]到dp[i]其实是一个类似于楼梯问题,这是一个完整可能结果的一条路径!所以+1是完全没有弄明白
"""
#官方题解
class Solution:
    def countTexts(self, pressedKeys: str) -> int:
        m = 10 ** 9 + 7
        dp3 = [1, 1, 2, 4]   # 连续按多次 3 个字母按键对应的方案数
        dp4 = [1, 1, 2, 4]   # 连续按多次 4 个字母按键对应的方案数
        n = len(pressedKeys)
        for i in range(4, n + 1):
            dp3.append((dp3[i-1] + dp3[i-2] + dp3[i-3]) % m)
            dp4.append((dp4[i-1] + dp4[i-2] + dp4[i-3] + dp4[i-4]) % m)
        res = 1   # 总方案数
        cnt = 1   # 当前字符连续出现的次数
        for i in range(1, n):
            if pressedKeys[i] == pressedKeys[i-1]:
                cnt += 1
            else:
                # 对按键对应字符数量讨论并更新总方案数
                if pressedKeys[i-1] in "79":
                    res *= dp4[cnt]
                else:
                    res *= dp3[cnt]
                res %= m
                cnt = 1
        # 更新最后一段连续字符子串对应的方案数
        if pressedKeys[-1] in "79":
            res *= dp4[cnt]
        else:
            res *= dp3[cnt]
        res %= m
        return res

2466. 统计构造好字符串的方案数

#初始状态定义为1,表示呆在原地?
class Solution:
    def countGoodStrings(self, low: int, high: int, zero: int, one: int) -> int:
        mi=min(zero,one)
        ma=max(zero,one)
        dp=[0]*(high+1)
        dp[0]=1
        for i in range(1,high+1):
            if i>=one:
                dp[i]=dp[i-one]
            if i>=zero:
                dp[i]+=dp[i-zero]
        return sum(dp[low:]) % (10**9+7)

标签:cnt,dp4,dp3,int,res,算法,数据结构,dp,动态
From: https://www.cnblogs.com/zzddkkhome/p/18201193

相关文章

  • 动态规划
    DP常见考虑角度状态表示以0/1背包问题为例:所求解问题用几维变量表示。常见的两维:$f_{i,j}$。两个考虑角度:集合+属性表示的集合是什么:所有选法的集合。条件:只从前\(i\)个物品里面选,总体积\(\leqslantj\)。集合的属性是什么:最大值、最小值、元素数量......
  • UE4 动态生成网格
    说明在游戏中动态改变网格数量和形状等,该功能是寻路功能的前期准备,即在基础移动地基上方,构建一层网格,任何移动的操作都可以基于该网格进行计算。从而在编辑器模式下能够更方便进行调试InstancedStaticMeshComponent其是一种用于优化静态网格渲染性能的技术。InstancedStaticMes......
  • Python之快排算法
    快排算法的思路:从list中取出下标为0的值定义三个list进行循环,大于list[0]放入一个A,小于的放入B,其他的放入C拼接:A+C+B代码实现:list=[13,8,11,17,5,6,1,1,1]defQuickSort(list):iflen(list)<=1:#判断如果小于等于1,则无需排序,直接返回即可......
  • 架构与思维:4大主流分布式算法介绍(图文并茂、算法拆解)
    0导读之前的文章中,我们介绍过分布式事务的基础知识,也了解了分布式场景下常见一致性问题和解决方案,对分布式锁和CAS模式有一定的了解,有兴趣的同学可以通过下面链接到作者的两篇相关文章。五种分布式事务解决方案(图文总结)高并发下的数据一致性保障(图文全面总结)1介绍本文聚......
  • Java中CAS算法的集中体现:Atomic原子类库,你了解吗?
    一、写在开头在前面的博文中我们学习了volatile关键字,知道了它可以保证有序性和可见性,但无法保障原子性,结局原子性问题推荐使用synchronized、Lock或者AtomicInteger;我们还学习过CAS算法,在那篇博文中我们同样也提及atomic。那么今天,我们就来好好学一学Atomic原子库,一个基于CAS算......
  • 一句话速通银行家算法
    一句话速通银行家算法:try分配资源,ifsafe()thencontinue;                     else归还资源并且sleep(当前任务).好,本文结束。hh其实并没有,接下来我将解释这句话以及银行家算法究竟是个啥。 ps:银行家算法是tryassign(), 而还有个锁的ap......
  • 代码随想录算法训练营第十三天 | 239. 滑动窗口最大值 347. 前k个高频元素
    239.滑动窗口最大值题目链接文章讲解视频讲解思路:使用单调队列,来维护有可能成为最大值的元素;   当窗口向右滑动时,判断移除的元素是否是队首元素如果是的话出队;   新加入的元素依次和队尾元素作比较,如果大于队尾元素则将队尾元素循环出队,这样可以保证队列中始终维持......
  • C++算法刷题基础
    1.main函数的返回类型一定是int2.C++语言为我们准备了一组内置库,包含了很多常用的功能,并且这些内置库可以直接使用,而其中的内置库:iostream,就提供了输入和输出的功能,允许开发者从键盘读取输入并在屏幕上输出结果。3.在iostream库中,我们有两个对象可以使用,分别是cin和cout。......
  • 在数据结构上,后端要求前端在一个对象中添加一个类型字段,并且对该对象的某些属性中都加
    这个需求的合理性取决于具体的应用场景和目的。让我们分析一下:合理性的一面:简化逻辑处理:如果这个类型字段是为了在后端快速区分或过滤不同类型的对象属性,那么在前端就做好标记,可以简化后端处理逻辑,减少在后端进行类型判断的需要。一致性保证:在前端加入类型字段并确保它与对象......
  • 新浪微博动态 RSA 分析图文+登录
    当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解新浪微博动态RSA分析图文+登录日期:2016-10-12阿珏教程浏览:3583次评论:5条新浪微博动态RSA分析一、用到的工具......