wordpress 换域名 全站301重定向/槐荫区网络营销seo

wordpress 换域名 全站301重定向,槐荫区网络营销seo,海外服务器租赁,关于网站建设的奖项名称动态规划合集——动态规划基本原理 动态规划原理1258:【例9.2】数字金字塔 动态规划原理深度优先搜索记忆化搜索动态规划(顺推)动态规划原理题解分析 滚动数组优化动态规划(逆推) 动态规划原理 从数塔问题出发理解动态…

动态规划合集——动态规划基本原理

  • 动态规划原理
    • 1258:【例9.2】数字金字塔 动态规划原理
      • 深度优先搜索
      • 记忆化搜索
      • 动态规划(顺推)
        • 动态规划原理
        • 题解分析
      • 滚动数组优化
      • 动态规划(逆推)

动态规划原理

从数塔问题出发理解动态规划。

1258:【例9.2】数字金字塔 动态规划原理

1258:【例9.2】数字金字塔

深度优先搜索

问题要求的是从最高点按照规则走到最低点的路径的最大的权值和,路径起点终点固定,走法规则明确,可以考虑用搜索来解决。

定义递归函数void Dfs(int x,int y,int Curr),其中(x,y)表示当前已从(1,1)走到(x,y),目前已走路径上的权值和为Curr。同时用另一个变量Ans记录最大值。

x=N时,到达递归出口,如果CurrAns大,则把Ans更新为Curr
否则向下一行两个位置行走,即递归执行
Dfs(x+1,y,Curr+A[x+1][y])Dfs(x+1,y+1,Curr+A[x+1][y+1])

该方法实际上是把所有路径都走了一遍,由于每一条路径都是由N-1步组成,每一步有“左”、“右”两种选择,因此路径总数为 2 N − 1 2^{N-1} 2N1
所以该方法的时间复杂度为 O ( 2 N − 1 ) O(2^{N-1}) O(2N1),铁定超时。

#include <iostream>
using namespace std;
int A[1005][1005], F[1005][1005], N, Ans;
void Dfs(int x, int y, int Curr) {if (x == N) {if (Curr > Ans)Ans = Curr;return;}//深度优先搜索是枚举所有情况,这里只有两个,而且用形参表示状态,回溯无难度Dfs(x + 1, y, Curr + A[x + 1][y]);Dfs(x + 1, y + 1, Curr + A[x + 1][y + 1]);
}
int main() {cin >> N;for (int i = 1; i <= N; i++)for (int j = 1; j <= i; j++)cin >> A[i][j];Ans = 0;Dfs(1, 1, A[1][1]);cout << Ans << endl;return 0;
}

记忆化搜索

为了避免重复搜索,我们在dfs的基础上开设全局数组F[x][y]记录从(x,y)出发到终点路径的最大权值和,一开始全部初始化为-1表示未被计算过。

在计算Dfs(x,y)时,首先查询F[x][y],如果F[x][y]不等于-1,说明Dfs(x,y)之前已经被计算过,直接返回 F[x][y]即可,否则计算出Dfs(x,y)的值并存储在F[x][y]中。

由于F[x][y]对于每个合法的(x,y)都只计算过一次,
而且计算是在 O ( 1 ) O(1) O(1)内完成的,因此时间复杂度为 O ( N 2 ) O(N^2) O(N2)。可以通过本题。

记忆化搜索的本质已经是动态规划。因为记忆化搜索也是记录走过的分支,相当于已经解决了子问题,再遍历这条路径时直接由子问题解决当前问题即可。

#include <iostream>
#include <algorithm>
using namespace std;
int A[505][505],
F[505][505],N;
int Dfs(int x,int y) {if (F[x][y]== -1) {if (x==N)F[x][y]=A[x][y];elseF[x][y]=A[x][y]+max(Dfs(x+1,y),Dfs(x+1,y+1));}return F[x][y];
}
int main() {cin >> N;for(int i = 1;i <= N;i ++)for(int j = 1;j <= i;j ++)cin >> A[i][j];for(int i = 1;i <= N;i ++)for(int j = 1;j <= i;j ++)F[i][j] = -1;Dfs(1,1);cout << F[1][1] << endl;return 0;
}

动态规划(顺推)

动态规划原理

动态规划(Dynamic Programming,简称dp)是1951年美国数学家R.Bellman等人提出。具体详见动态规划_百度百科。

简单总结就是

  1. 一个大问题拆分成若干子问题,每个子问题的结果都是一个状态

  2. 由一个子问题解决另一个子问题选择的方法称为决策,在现实解决问题时我们都希望找到最优解,也就是最优决策

  3. 同一个大问题拆分成的子问题之间往往都有一样的规律。或者说,同一个大问题产生的任意两个不同状态之间有相同的联系。这个联系一般用数学公式表达,这个公式的专业术语叫状态转移方程

  4. 动态规划满足两个条件:

    • 最优化原理:每一步决策都是最好的解决方案,都是从很多方案中选择最好的方案。
    • 无后效性:每个状态除了第一个,都只由前阶段的状态和决策决定,和后续无关。
题解分析

1、状态定义:
题目要求从(1,1)出发到最底层路径最大权值和,路径中是各个点串联而成,路径起点固定,终点和中间点相对不固定。因此定义F[x][y]表示从(1,1)出发到达(x,y)的路径最大权值和。
最终答案Ans=max{F[N][1],F[N][2],...,F[N][N]}

2、状态转移方程&边界条件(或初始化方式):
不去考虑(1,1)(x,y)的每一步是如何走的,只考虑最后一步是如何走,根据最后一步是向
左还是向右分成以下两种情况:
向左:最后一步是从(x-1,y)走到(x,y), 此类路径被分割成两部分,

第一部分是从(1,1)走到(x-1,y),第二部分是从(x-1,y)走到(x,y)

第一部分的最大权值和,此部分问题的性质与F[x][y]的定义一样,就是F[x-1][y]

第二部分就是A[x][y],两部分相加即得到此类路径的最大权值和为F[x-1,y]+A[x,y]

向右: 最后一步是从(x-1,y-1)走到(x,y),此类路径被分割成两部分,

第一部分是从(1,1)走到(x-1,y-1),第二部分是从(x-1,y-1)走到(x,y),分析方法如上。

此类路径的最大权值和为
F[x-1,y-1]+A[x,y]

F[x][y]的计算需要求出上面两种情况的最大值。

综上,得到状态转移方程如下:
F[x][y]=max{F[x-1,y-1],F[x-1][y]}+A[x,y]

与递归关系式还需要递归终止条件一样,这里我们需要对边界进行处理以防止无休止地进行下去。观察发现计算F[x][y]时需要用到F[x-1][y-1]F[x-1][y],是上一行的元素,随着递归的深入,
最终都要用到第一行的元素F[1][1], F[1][1]的计算不能再使用状态转移方程来求,而是应该直接赋予一个特值A[1][1]。这就是边界条件

综上得:
状态转移方程F[x][y]=max{F[x-1][y-1],F[x-1][y]}+A[x,y]
边界条件F[1][1]=A[1][1]

分析该动态规划的正确性,分析该解法是否满足使用动态规划的两个前提。

最优化原理:这个在分析状态转移方程时已经分析得比较透彻,明显是符合最优化原理的。

无后效性:状态转移方程中,我们只关心F[x-1][y-1]F[x-1][y]的值,计算F[x-1][y-1]时可能有多种不同的决策对应着最优值,选哪种决策对计算F[x][y]的决策没有影响,
F[x-1][y]也是一样。这就是无后效性。

在以后的题目中可能不会提及,但处处都充斥着这两个前提的分析。

3、填表(或程序实现):
由于状态转移方程就是递归关系式,边界条件就是递归终止条件,所以可以用递归来完成,递归存在重复调用,利用记忆化可以解决重复调用的问题,这就是方法二的记忆化搜索

记忆化实现比较简单,而且不会计算无用状态,但递归也会受到栈的大小递推加回归执行方式的约束,另外记忆化实现调用状态的顺序是按照实际需求而展开,没有大局规划,不利于进一步优化

所以dp更常用的还是迭代法。状态用二维数组表示,也就是说可以通过循环的方式求出每个状态(通俗点称呼就是填表)。

计算F[x][y]用到状态F[x-1][y-1]F[x-1][y],这些元素在F[x][y]的上一行,也就是说要计算第x行的状态的值,必须要先把第x-1行元素的值计算出来,因此我们可以先把第一行元素F[1][1]赋为 A[1][1],再从第二行开始按照行从左到右递增从上到下递增的顺序通过循环计算出每一行的有效状态即可。时间复杂度为 O ( N 2 ) O(N^2) O(N2)

参考程序:

#include <iostream>
#include <algorithm>
using namespace std;
int A[1005][1005], F[1005][1005], N;
int main() {cin >> N;for (int i = 1; i <= N; i++)for (int j = 1; j <= i; j++)cin >> A[i][j];F[1][1] = A[1][1];for (int i = 2; i <= N; i++)for (int j = 1; j <= i; j++)F[i][j] = max(F[i - 1][j - 1], F[i - 1][j]) + A[i][j];int ans = 0;for (int i = 1; i <= N; i++)ans = max(ans, F[N][i]);cout << ans << endl;return 0;
}

滚动数组优化

根据之前得到的状态转移方程F[x][y]=max{F[x-1][y-1],F[x-1][y]}+A[x,y]
边界条件F[1][1]=A[1][1]

发现在二维数组表示的转移方程中,每个状态都只和上一个状态有关。而且每个状态都只和前1个状态有关,和前2个以及之前的所有状态都无关。

所以可以将表示状态的dp表用一维数组表示。状态转移方程变为

f[x]=max(f[x],f[x-1])+A[x,y]

这种不改变空间复杂度,但可以极大程度地优化空间复杂度的状态表示称作滚动数组优化。

在填表的时候,需要将循环从右往左枚举,才能保证每个状态都是正确的。

请添加图片描述

因为都是正数,所以不必考虑边界为0时造成的影响。如果存在负数,则可能需要对边界情况做判断,或取无穷小。

滚动数组优化参考程序:

#include<bits/stdc++.h>
using namespace std;int main() {int n;cin >> n;vector<vector<int> >A(1, vector<int>(2,0));vector<int>f(n+1,0);for (int i = 1; i <= n; i++) {A.push_back(vector<int>(i + 2, 0));for (int j = 1; j <= i; j++)cin >> A[i][j];}int ans = A[1][1];for (int i = 1; i <= n; i++) {for (int j = i; j >= 1; j--) {//逆向枚举f[j] = max(f[j], f[j - 1]) + A[i][j];ans = max(ans, f[j]);}}cout << ans;return 0;
}

整体来说滚动数组优化的步骤:

  1. 先用二维或多维解决问题。
  2. 若状态转移方程的状态只和上一层或上几层格子有关,则可以考虑优化。否则不能优化。
  3. 若判断出可以优化,则将原来的二维和多维状态减少适当的维度,并看情况修改循环的枚举顺序。

当然不是所有的题都能做空间优化。

动态规划(逆推)

这里思路和之前是一样的,只是状态的设定不同。

以这个样例为例:

5
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11

自底向上计算:(给出递推式和终止条件)

从底层开始,本身数即为最大数;

倒数第二层的计算,取决于底层的数据,每次都取最大:
12 + 6 = 18 , 13 + 14 = 27 , 24 + 15 = 39 , 24 + 8 = 32 12+6=18,13+14=27,24+15=39,24+8=32 12+6=1813+14=2724+15=3924+8=32
倒数第三层的计算,取决于底二层计算的数据,每次都取最大:
27 + 12 = 39 , 39 + 7 = 46 , 39 + 26 = 65 27+12=39,39+7=46,39+26=65 27+12=3939+7=4639+26=65
倒数第四层的计算,取决于底三层计算的数据,每次都取最大:
46 + 11 = 57 , 65 + 8 = 73 46+11=57,65+8=73 46+11=5765+8=73
最后的路径:
5—>13—>8->26—>15—>24

这是手搓简单情况,复杂情况人的效率远远不及计算机,需要交给计算机来做。

数据结构及算法设计

图形转化:直角三角形,便于搜索:向下、向右。

用三维数组表示数塔:

a[x][y][1]表示行、列及结点本身数据,
a[x][y][2]能够取得最大值,
a[x][y][3]表示前进的方向,0表示向下,1表示向右。

算法实现

数组初始化,输入每个结点值及初始的最大路径、前进方向为0;从倒数第二层开始向上一层求最大路径,共循环N-1次;从顶向下,输出路径:究竟向下还是向右取决于列的值,若列的值比原先多则向右,否则向下。

#include<iostream>
using namespace std;
int main()
{int n, x, y;int a[1001][1001][4]={0};cin >> n;for (x = 1; x <= n; x++)//输入数塔的初始值for (y = 1; y <= x; y++) {cin >> a[x][y][1];//1表示值a[x][y][2] = a[x][y][1];//2表示当前状态,未经计算时默认是原来的数a[x][y][3] = 0;//3表示路径走向,默认向下}for (x = n - 1; x >= 1; x--)//从倒数第二行开始推 for (y = 1; y <= x; y++)if (a[x + 1][y][2] > a[x + 1][y + 1][2]) {//选择最大路径值a[x][y][2] = a[x][y][2] + a[x + 1][y][2];a[x][y][3] = 0;}else {a[x][y][2] = a[x][y][2] + a[x + 1][y + 1][2];a[x][y][3] = 1;}cout << a[1][1][2] << endl;//输出数塔最大值枚举路径,这题可忽略//y = 1;//for (x = 1; x <= n - 1; x++){//输出数塔最大值的路径//	cout << a[x][y][1] << "->";//	y = y + a[x][y][3];//下一行的列数//}//cout << a[n][y][1] << endl;return 0;
}

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

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

相关文章

如何让节卡机器人精准对点?

如何让节卡机器人精准对点&#xff1f; JAKA Zu 软件主界面主要由功能栏、开关栏、菜单栏构成。 菜单栏&#xff1a;控制柜管理&#xff0c;机器人管理与软件管理组成。主要功能为对控制柜关机、APP 设置、机器人本体设 置、控制柜设置、连接机器人和机器人显示等功能。 开关…

实时视频分析的破局之道:蓝耘 MaaS 如何与海螺 AI 视频实现高效协同

一、蓝耘 MaaS 平台&#xff1a;AI 模型全生命周期管理的智能引擎 蓝耘 MaaS&#xff08;Model-as-a-Service&#xff09;平台是由蓝耘科技推出的 AI 模型全生命周期管理平台&#xff0c;专注于为企业和开发者提供从模型训练、推理到部署的一站式解决方案。依托云原生架构、高…

设计模式(行为型)-策略模式

目录 定义 类图 角色 角色详解 Strategy&#xff08;抽象策略类&#xff09;​ Context&#xff08;环境类 / 上下文类&#xff09;​ ConcreteStrategy&#xff08;具体策略类&#xff09;​ 优缺点 优点​ 缺点​ 使用场景 类行为差异场景​ 动态算法选…

【算法day14】三数之和

三数之和 https://leetcode.cn/problems/3sum/description/ 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。…

10、STL中的unordered_map使用方法

一、了解 1、unordered_map(哈希) unordered_map是借用哈希表实现的关联容器。 访问键值对O&#xff08;1&#xff09;&#xff0c;最坏情况O&#xff08;n&#xff09;&#xff0c;例如哈希冲突严重时。【n是一个哈希桶的元素数量】 unordered_map特性 键值对存储&#xff…

C++ 头文件说明

如果一个程序足够大&#xff0c;代码功能很多&#xff0c;可以想象&#xff0c;不可能把代码写在一个cpp文件里。我们需要模块化&#xff0c;这样的好处很多&#xff0c;方便分工合作&#xff0c;可读性提高&#xff0c;调用也方便。 这个要怎么做呢&#xff1f; 很简单直接当…

【Linux系统】Linux进程终止的N种方式

Linux系列 文章目录 Linux系列前言一、进程终止的概念二、进程终止的场景三、进程终止的实现3.1 程序退出码3.2 运行完毕结果正常3.3 运行完毕结果异常3.4 程序异常退出 总结 前言 进程终止是操作系统中&#xff0c;进程的一个重要阶段&#xff0c;他标志着进程生命周期的结束…

【工具类】Java的 LocalDate 获取本月第一天和最后一天

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

嵌入式开发之STM32学习笔记day06

基于STM32F103C8T6的开发实践——从入门到精通01 1. 引言 STM32系列微控制器是STMicroelectronics推出的一款高性能、低功耗的32位微控制器&#xff0c;广泛应用于嵌入式系统中。STM32F103C8T6是其中非常受欢迎的一款&#xff0c;凭借其强大的性能、丰富的外设接口和低廉的价格…

AutoHub场景演示|带您领略智能自动化操作的全新体验

AutoHub是一款由OpenCSG推出的基于前沿大型语言模型&#xff08;LLM&#xff09;的浏览器自动化工具&#xff0c;旨在通过智能对话交互和自动化技术&#xff0c;帮助用户更高效地浏览网页和完成任务。它不仅能够自动化繁琐的网页操作&#xff0c;还能够为用户提供精准的信息检索…

深入解析 Linux 声卡驱动:从架构到实战

在嵌入式 Linux 设备中&#xff0c;音频功能的实现离不开 Linux 声卡驱动。而 ALSA (Advanced Linux Sound Architecture) 作为 Linux 内核的音频框架&#xff0c;提供了一整套 API 和驱动模型&#xff0c;帮助开发者快速集成音频功能。本篇文章以 WM8960 音频编解码器&#xf…

虚拟地址空间(下)进程地址空间(上)

一.关于页表组成 1.权限&#xff08;rwx) 作用&#xff1a;如1.让代码区变成只读的 2.写时拷贝的实现&#xff1a;子进程创建时其页表指向的父进程代码和数据权限都是只读的&#xff0c;子进程试图修改&#xff0c;触发错误&#xff0c;系统开始写时拷贝。 来源&#xff1a;…

iwebsec-SQL数字型注入

1.判断是否存在漏洞 添加and 11发现正常显示&#xff0c;添加and 12无回显条目&#xff0c;则存在sql注入漏洞 2.因为有回显&#xff0c;尝试union联合注入&#xff0c;使用order by判断出有3个字段 3.使用union联合注入查看回显位&#xff0c;发现3三个字段均有回显&#xff…

蓝桥杯每日五题第一日

蓝桥杯每日5题 问题一 班级活动 1.班级活动 - 蓝桥云课 问题描述 小明的老师准备组织一次班级活动。班上一共有 nn 名 (nn 为偶数) 同学&#xff0c;老师想把所有的同学进行分组&#xff0c;每两名同学一组。为了公平&#xff0c;老师给每名同学随机分配了一个 nn 以内的正…

前端字段名和后端不一致?解锁 JSON 映射的“隐藏规则” !!!

&#x1f680; 前端字段名和后端不一致&#xff1f;解锁 JSON 映射的“隐藏规则” &#x1f31f; 嘿&#xff0c;技术冒险家们&#xff01;&#x1f44b; 今天我们要聊一个开发中常见的“坑”&#xff1a;前端传来的 JSON 参数字段名和后端对象字段名不一致&#xff0c;会发生…

【Linux】Bash是什么?怎么使用?

李升伟 整理 什么是 Bash&#xff1f; Bash&#xff08;Bourne Again Shell&#xff09;是一种 命令行解释器&#xff08;Shell&#xff09;&#xff0c;广泛用于 Unix 和 Linux 操作系统。它是 Bourne Shell&#xff08;sh&#xff09; 的增强版&#xff0c;提供了更多的功能…

Qt Creator入门

1.创建项目 选择创建项目-Application&#xff08;Qt&#xff09;-Qt Widgets Application-修改名称即可 默认创建有窗口类&#xff0c;myWidget,基类有三种选择&#xff1a;QWidget&#xff0c;QMainWindow&#xff0c;QDialog 注意&#xff1a; 名称和创建路径不能有中文、…

咖啡点单小程序毕业设计(JAVA+SpringBoot+微信小程序+完整源码+论文)

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着社会的快速发展和…

003-掌控命令行-CLI11-C++开源库108杰

首选的现代C风格命令行参数解析器! &#xff08;本课程包含两段教学视频。&#xff09; 以文件对象监控程序为实例&#xff0c;五分钟实现从命令行读入多个监控目标路径&#xff1b;区分两大时机&#xff0c;学习 CLI11 构建与解析参数两大场景下的异常处理&#xff1b;区分三…

谱分析方法

前言 本文隶属于专栏《机器学习数学通关指南》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见《机器学习数学通关指南》 ima 知识库 知识库广场搜索&#…