算法——动态规划(DP,Dynamic Programming)

一、基础概念 

  • DP的思想:
    • 把问题分成子问题,前面子问题的解决结果被后面的子问题使用
  • DP与分治法的区别:
    • 分治法把问题分成独立的子问题,各个子问题能独立解决
      • 自顶向下
    • DP前面子问题的解决结果被后面的子问题使用,子问题间不相互独立
      • 自底向上
  • 求解DP问题的步骤:
    • 1、定义状态
    • 2、状态转移 
      • 确定状态转移方程
    • 3、算法实现
  • DP问题分类:
    • 1、线性DP
    • 2、非线性DP
  • DP问题解决方法:
    • 顺推
    • 逆推
  • DP可以解决的问题需满足三个条件:
    • 1、问题有最优解
    • 2、有大量子问题重复(DP可以把求解的结果存起来,后续用到时直接查询)
    • 3、当前阶段的求解只与前面的阶段有关,与之后的阶段无关

 二、爬楼梯(一维)

假设有n(1\leq n\leq 50)级楼梯,每次只能爬1级或2级,有多少种方法可以爬到楼梯的顶部?

分析:

  • 在爬上第 i 级楼梯之前 ,爬楼梯的人一定站在第 i-1 级楼梯或第 i-2 级楼梯上,两种情况
  • 所以爬上第 i 级楼梯的方法等于两种走法之和(站在第i-1级楼梯,站在第i-2级楼梯上)
  • 此处涉及到应用组合数学的加法规则:(“或”)
    • 如果一个事件以 a 种方式发生,第二个事件以 b 种(不同)方式发生,那么存在 a+b 种方式
  • dp[i]表示爬上第i级楼梯有多少种走法
    • dp[1]=1
    • dp[2]=2
    • dp[i]=dp[i-1]+dp[i-2],i>2(状态转移方程)

1、辅助数组

时间复杂度O(n),空间复杂度O(n)

package no1_1;
import java.util.Scanner;
public class example {public static void main(String[] args) {Scanner sc=new Scanner(System.in);int n=sc.nextInt();int[] dp=new int[n+1];dp[1]=1;dp[2]=2;for(int i=3;i<=n;i++) {dp[i]=dp[i-2]+dp[i-1];}System.out.println(dp[n]);}
}

2、只使用两个变量记录前两项的值

时间复杂度O(n),空间复杂度O(1)

package no1_1;
import java.util.Scanner;
public class example {public static void main(String[] args) {Scanner sc=new Scanner(System.in);int n=sc.nextInt();int val1=1,val2=2,result=0;;for(int i=3;i<=n;i++) {//val1:前一项;val2:当前项result=val1+val2;val1=val2;val2=result;}System.out.println(result);}
}

三、拿金币(二维)

有一个N x N的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。你站在最左上角的格子里,每次可以从一个格子走到它右边或下边的格子里。请问如何走才能拿到最多的金币。

分析:

  • 当前位的最大金币数,需要上一位也拿到最大金币数

package no1_1;
import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();//根据输入,把金币放入数组中对应的位置int[][] goldCoins = new int[n + 1][n + 1];for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {goldCoins[i][j] = scanner.nextInt();}}//该数组存储的是走到当前位置所拿的最多金币数int[][] sum = new int[n + 1][n + 1];for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {//当前位的最大金币数,需要上一位也拿到最大金币数,//该循环看的是sum[i][j],一直是往前走的,不要被i-1和j-1误了眼,觉得是倒退着走,i-1和j-1只是判断上一步是应该在哪里if (sum[i][j - 1] > sum[i - 1][j]) {sum[i][j] = sum[i][j - 1] + goldCoins[i][j];} else {sum[i][j] = sum[i - 1][j] + goldCoins[i][j];}}}System.out.println(sum[n][n]);}
}

四、印章(二维)

共有n种图案的印章,每种图案的出现概率相同。小A买了m张印章,求小A集齐n种印章的概率。

分析:

  • i:买的印章数
  • j:凑齐的印章数
  • dp[i][j]:买了 i 个印章,凑齐了 j 种的概率
  • 概率 p=1 / n 
  • 情况一:
    • i < j
    • 不可能凑齐,dp[i][j]=0
  • 情况二:
    • j == 1
    • 买了 i 张印章,凑齐的印章为图案1时,概率为p^{i}
    • 但有 n 种印章图案,总的概率等于每个种图案的概率和(应用组合数学的加法规则 )
    • p^{i}\times n,而 p = 1 / n,所以
    • dp\left [ i \right ]\left [ 1 \right ]=(\frac{1}{n})^{i-1}
  • 情况三:
    • i >= j

    • 为下面两种情况相加(应用组合数学的加法规则)

    • 1、买了 i - 1 张 已经得到了 j 种,最后一张随便

      • dp[i] [j] = dp[i-1] [j] * ( j / n )

        • dp[i-1] [j]是买了 i - 1 张 已经得到了 j 种的概率

        • j / n是最后一张随便哪种的概率

    • 2、买了 i - 1 张 只得到了 j - 1 种,最后一张是第 j 种

      • dp[i] [j] = dp[i-1] [j-1] * (n-(j-1)) / n

        • dp[i-1] [j-1]是买了 i - 1 张 只得到了 j - 1 种的概率

        • (n-(j-1)) / n是买最后一张是第 j 种的概率

package no1_1;
import java.util.*;
public class Main {public static void main(String[] args) {    	Scanner sc=new Scanner(System.in); int n=sc.nextInt();int m=sc.nextInt();double[][] array=new double[m+1][n+1];System.out.printf("%.4f",probability(array,n,m));//动态规划}public static double probability(double[][] array,int n,int m) {double p=1.0/n;for(int i=1;i<=m;i++) {//买的印章数for(int j=1;j<=n;j++) {//凑齐的印章数if(i<j) {//买的印章数少于种类数,不可能凑齐array[i][j]=0;}else if(j==1) {//只凑齐了一种array[i][j]=Math.pow(p, i-1);}else {//为下面两种情况相加,(应用组合数学的加法规则)//1、买了 i - 1 张 已经得到了 j 种,最后一张随便, dp[i] [j] = dp[i-1] [j] * ( j / n )//2、买了 i - 1 张 只得到了 j - 1 种,最后一张是第 j 种, dp[i] [j] = dp[i-1] [j-1] * (n-j+1) / narray[i][j]=array[i-1][j]*(j*p)+array[i-1][j-1]*((n-j+1)*p);}}}return array[m][n];}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/231049.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【基于APB总线的DES实现】

基于APB总线的DES实现 本文内容摘要APB介绍仿真结果整体仿真写入数据DES加密部分DES加密读出密文 整体代码 本文内容摘要 本文是设计一个可兼容APB总线的DES加密协处理器&#xff0c;用来将DES加密模块与APB总线进行对接&#xff0c;使总线发送来的数据可以正常写入并进行加密后…

Autosar DEM DTC的Debounce策略

文章目录 简介Debounce策略1、基于计数器的 Debounce 策略2、基于时间的Debounce策略 简介 故障事件防抖&#xff0c;与按键防抖&#xff08;软件需要延时确认按键不是误触发&#xff09;的作用类似&#xff0c;目的是为了防止事件误触发采取的策略。 因为DTC并不是一达到触发…

产品调研——AI平台

本文主要记录了对腾讯云-TIONE平台、华为云-ModelArt等主流AI平台的产品调研。 交互式建模 简单点说就是提供了带训练资源的云IDE&#xff0c;使用形态包括Notebook、VsCode等。 腾讯云-TI平台 TI平台将tensorflow、pytorch、spark环境等均集成到一个Notebook容器中&#xf…

Android 一分钟使用RecyclerView完美实现瀑布

【免费】安卓RecyclerView瀑布流效果实现资源-CSDN文库 1.WaterfallFlowActivity 主函数代码&#xff1a; package com.example.mytestapplication;import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.widget.Toast;im…

Git总结 | Git面试都问些啥?

什么是Git为什么要用Git等等这些相信看到该标题点进来的同学也不希望浪费时间再看一遍&#xff0c;那么直接进入主题&#xff0c;对于日常工作中常用的Git相关操作进行整理&#xff0c;一起看看吧 面试官&#xff1a;你常用的Git操作是什么? 候选人&#xff1a;git clone 面试…

59. 螺旋矩阵 II(java实现,史上最详细教程,想学会的进!!!)

今天来分享一下螺旋矩阵的解题思路及代码的实现。 题目描述如下&#xff1a; 首先拿到这道题&#xff0c;首先不要慌张&#xff0c;我们来仔细分析一下会发现并没有那么难。 首先看下边界的元素是1、2、3递增的&#xff0c;那么我们也许可以根据这一点先把边界的元素一个一个给…

【Proteus仿真】【51单片机】视力保护仪

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使LCD1602液晶&#xff0c;按键、HC-SR04超声波、PCF8591 ADC、光敏传感器、蜂鸣器、LED等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示…

【vtkWidgetRepresentation】第十四期 二维标注

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享vtk中的二维标注,主要用于医学领域,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 目录 前言 1. vtkBiDimension…

漏洞复现-海康威视 NCG 联网网关 login.php 目录遍历漏漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

Day64力扣打卡

打卡记录 方格取数&#xff08;线性DP&#xff09; import sys input sys.stdin.readline 输入样例&#xff1a; 8 2 3 13 2 6 6 3 5 7 4 4 14 5 2 21 5 6 4 6 3 15 7 2 14 0 0 0 输出样例&#xff1a; 67 n int(input()) w [[0] * (n 1) for _ in range(n 1)] while Tru…

精选硬件连通性测试工具:企业如何做出明智选择

在当今数字化的商业环境中&#xff0c;企业的硬件连通性至关重要。选择适用的硬件连通性测试工具是确保网络和设备协同工作的关键一步。本文将探讨企业在选择硬件连通性测试工具时应考虑的关键因素&#xff0c;以帮助其做出明智的决策。 1. 功能全面性&#xff1a;首要考虑因素…

Android开发——组合函数、注解与连接Android设备

1、JetPack Compose、组合函数与注解和文本修改 1、JetPack Compose&#xff1a;Jetpack Compose 是由 Google 推出的用于构建 Android 用户界面的现代化工具包。它是一个声明式的 UI 工具包&#xff0c;用于简化 Android 应用程序的用户界面设计和开发。Jetpack Compose 采用…

C语言精选练习题:(11)打印菱形

文章目录 每日一言题目思路代码结语 每日一言 Intelligence without ambition is a bird without wings. 聪明但没有抱负&#xff0c;就像没有翅膀的鸟。 题目 输入一个整数n&#xff0c;打印对应2n-1行的菱形图案&#xff0c;比如输入7&#xff0c;图案一共13行 1 …

Stable Diffusion - High-Resolution Image Synthesis with Latent Diffusion Models

Paper name High-Resolution Image Synthesis with Latent Diffusion Models Paper Reading Note Paper URL: https://arxiv.org/abs/2112.10752 Code URL: https://github.com/CompVis/latent-diffusion TL;DR 2021 年 runway 和慕尼黑路德维希马克西米利安大学出品的文…

全球移动通信(2G/3G/4G/5G)频谱分布情况

一、概述 随着通信技术的不断发展&#xff0c;全球各国都在积极推进2G、3G、4G、5G网络的建设和应用。根据FCC统计&#xff0c;目前全球移动通信频谱分布如下&#xff1a; 二、分布 &#xff08;一&#xff09;俄罗斯 2G&#xff1a;主要使用900MHz和1800MHz两个频段。其中&…

【sqli靶场】第六关和第七关通关思路

目录 前言 一、sqli靶场第六关 1.1 判断注入类型 1.2 观察报错 1.3 使用extractvalue函数报错 1.4 爆出数据库中的表名 二、sqli靶场第七关 1.1 判断注入类型 1.2 判断数据表中的字段数 1.3 提示 1.4 构造poc爆库名 1.5 构造poc爆表名 1.6 构造poc爆字段名 1.7 构造poc获取账…

【Axure RP9】动态面板使用------案例:包括轮播图和多方式登入及左侧菜单栏案例

目录 一 动态面板简介 1.1 动态面板是什么 二 轮播图 2.1 轮播图是什么 2.2 轮播图应用场景 2.3 制作实播图 三 多方式登入 3.1多方式登入是什么 3.3 多方式登入实现 四 左侧菜单栏 4.1左侧菜单栏是什么 4.2 左侧菜单栏实现 一 动态面板简介 1.1 动态面板是什么…

【LeetCode刷题笔记(5)】【Python】【盛最多水的容器】【双指针】【中等】

文章目录 盛最多水的容器算法题描述示例示例 1示例 2 提示题意拆解 解决方案&#xff1a;【双指针】运行结果复杂度分析 结束语 盛最多水的容器 盛最多水的容器 算法题描述 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (…

Surface pro官方镜像恢复详细图文步骤

某些小白不会弄直接找淘宝远程刷官方系统&#xff0c;还被忽悠什么原版序列号会抹掉这样的笑话&#xff0c;真的很无语 一、准备恢复优盘 1、微软官方下载中心&#xff0c;按序列号下载&#xff0c;对应镜像&#xff0c;推荐最新版&#xff0c;但一般都要有注册微软账号才能下…

微信小程序背景图片设置

问题 :微信小程序通过css:background-image引入背景图片失败 [渲染层网络层错误] pages/wode/wode.wxss 中的本地资源图片无法通过 WXSS 获取&#xff0c;可以使用网络图片&#xff0c;或者 base64&#xff0c;或者使用<image/>标签 解决方法微信小程序在使用backgroun…