第18节 动态规划一讲

news2024/11/26 1:33:11

1假设有排成一行的N个位置记为1~N,N一定大于或等于2
开始时机器人在其中的M位置上(M一定是1~N中的一个)
如果机器人来到1位置,那么下一步只能往右来到2位置;
如果机器人来到N位置,那么下一步只能往左来到N-1位置;
如果机器人来到中间位置,那么下一步可以往左走或者往右走;
规定机器人必须走K步,最终能来到P位置(P也是1~N中的一个)的方法有多少种
给定四个参数 N、M、K、P,返回方法数

动态规划:如果在调用过程中有重复调用过程就将他存起来

比如递归求斐波那契数列,中间有不少重复过程

 递归策略:

#include <vector>

using namespace std;

class Solution {
public:
    int ways1(int N, int start, int aim, int K) {
        if (N < 2 || start < 1 || start > N || aim < 1 || aim > N || K < 1) {
            return -1;
        }
        return process1(start, K, aim, N);
    }
/ 机器人当前来到的位置是cur,
	// 机器人还有rest步需要去走,
	// 最终的目标是aim,
	// 有哪些位置?1~N
	// 返回:机器人从cur出发,走过rest步之后,最终停在aim的方法数,是多少?

private:
    int process1(int cur, int rest, int aim, int N) {
        if (rest == 0) {
            return cur == aim ? 1 : 0;
        }
        if (cur == 1) {
            return process1(2, rest - 1, aim, N);
        }
        if (cur == N) {
            return process1(N - 1, rest - 1, aim, N);
        }
        return process1(cur - 1, rest - 1, aim, N) + process1(cur + 1, rest - 1, aim, N);
    }
};

这个递归来进行优化

该递归中出现了重复解

cur范围1到n

rest范围0到k

准备一张dp表,先全设为-1,表示没算过这个过程

#include <vector>

using namespace std;

class Solution {
public:
    int ways2(int N, int start, int aim, int K) {
        if (N < 2 || start < 1 || start > N || aim < 1 || aim > N || K < 1) {
            return -1;
        }
        vector<vector<int>> dp(N + 1, vector<int>(K + 1, -1));
        return process2(start, K, aim, N, dp);
    }

private:
    int process2(int cur, int rest, int aim, int N, vector<vector<int>>& dp) {
        if (dp[cur][rest] != -1) {
            return dp[cur][rest];
        }//算过的值就塞入缓存表
        int ans = 0;
        if (rest == 0) {
            ans = cur == aim ? 1 : 0;
        }
        else if (cur == 1) {
            ans = process2(2, rest - 1, aim, N, dp);
        }
        else if (cur == N) {
            ans = process2(N - 1, rest - 1, aim, N, dp);
        }
        else {
            ans = process2(cur - 1, rest - 1, aim, N, dp) + process2(cur + 1, rest - 1, aim, N, dp);
        }
        dp[cur][rest] = ans;//没算过的算出来了也塞入缓存表
        return ans;
    }
};

 再往下优化,直接填这张动态规划表

 

不要硬憋状态转移,要去想尝试策略

#include <vector>

using namespace std;

class Solution {
public:
    int ways3(int N, int start, int aim, int K) {
        if (N < 2 || start < 1 || start > N || aim < 1 || aim > N || K < 1) {
            return -1;
        }
        vector<vector<int>> dp(N + 1, vector<int>(K + 1, 0));
        dp[aim][0] = 1;
        for (int rest = 1; rest <= K; rest++) {
            dp[1][rest] = dp[2][rest - 1];
            for (int cur = 2; cur < N; cur++) {
                dp[cur][rest] = dp[cur - 1][rest - 1] + dp[cur + 1][rest - 1];
            }
            dp[N][rest] = dp[N - 1][rest - 1];
        }
        return dp[start][K];
    }
};

 2给定一个整型数组arr,代表数值不同的纸牌排成一条线
玩家A和玩家B依次拿走每张纸牌
规定玩家A先拿,玩家B后拿
但是每个玩家每次只能拿走最左或最右的纸牌
玩家A和玩家B都绝顶聪明
请返回最后获胜者的分数

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int f1(vector<int>& arr, int L, int R);
int g1(vector<int>& arr, int L, int R);

int win1(vector<int>& arr) {
    if (arr.empty()) {
        return 0;
    }
    int first = f1(arr, 0, arr.size() - 1);
    int second = g1(arr, 0, arr.size() - 1);
    return max(first, second);
}

int f1(vector<int>& arr, int L, int R) {
    if (L == R) {
        return arr[L];
    }
    int p1 = arr[L] + g1(arr, L + 1, R);
    int p2 = arr[R] + g1(arr, L, R - 1);
    return max(p1, p2);
}

int g1(vector<int>& arr, int L, int R) {
    if (L == R) {
        return 0;
    }
    int p1 = f1(arr, L + 1, R); // 对手拿走了L位置的数
    int p2 = f1(arr, L, R - 1); // 对手拿走了R位置的数
    return min(p1, p2);
}

int main() {
    vector<int> arr = {3, 9, 1, 2};
    cout << win1(arr) << endl; // 示例输入,输出结果根据实际情况可能不同
    return 0;
}

 弄两张表进行记忆化缓存

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int f2(vector<int>& arr, int L, int R, vector<vector<int>>& fmap, vector<vector<int>>& gmap);
int g2(vector<int>& arr, int L, int R, vector<vector<int>>& fmap, vector<vector<int>>& gmap);

int win2(vector<int>& arr) {
    if (arr.empty()) {
        return 0;
    }
    int N = arr.size();
    vector<vector<int>> fmap(N, vector<int>(N, -1));
    vector<vector<int>> gmap(N, vector<int>(N, -1));
    int first = f2(arr, 0, arr.size() - 1, fmap, gmap);
    int second = g2(arr, 0, arr.size() - 1, fmap, gmap);
    return max(first, second);
}

int f2(vector<int>& arr, int L, int R, vector<vector<int>>& fmap, vector<vector<int>>& gmap) {
    if (fmap[L][R] != -1) {
        return fmap[L][R];
    }
    int ans = 0;
    if (L == R) {
        ans = arr[L];
    } else {
        int p1 = arr[L] + g2(arr, L + 1, R, fmap, gmap);
        int p2 = arr[R] + g2(arr, L, R - 1, fmap, gmap);
        ans = max(p1, p2);
    }
    fmap[L][R] = ans;
    return ans;
}

int g2(vector<int>& arr, int L, int R, vector<vector<int>>& fmap, vector<vector<int>>& gmap) {
    if (gmap[L][R] != -1) {
        return gmap[L][R];
    }
    int ans = 0;
    if (L != R) {
        int p1 = f2(arr, L + 1, R, fmap, gmap); // 对手拿走了L位置的数
        int p2 = f2(arr, L, R - 1, fmap, gmap); // 对手拿走了R位置的数
        ans = min(p1, p2);
    }
    gmap[L][R] = ans;
    return ans;
}

int main() {
    vector<int> arr = {3, 9, 1, 2};
    cout << win2(arr) << endl; // 示例输入,输出结果根据实际情况可能不同
    return 0;
}

 

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int win3(vector<int>& arr) {
    if (arr.empty()) {
        return 0;
    }
    int N = arr.size();
    vector<vector<int>> fmap(N, vector<int>(N));
    vector<vector<int>> gmap(N, vector<int>(N));

    for (int i = 0; i < N; i++) {
        fmap[i][i] = arr[i];
    }

    for (int startCol = 1; startCol < N; startCol++) {
        int L = 0;
        int R = startCol;
        while (R < N) {
            fmap[L][R] = max(arr[L] + gmap[L + 1][R], arr[R] + gmap[L][R - 1]);
            gmap[L][R] = min(fmap[L + 1][R], fmap[L][R - 1]);
            L++;
            R++;
        }
    }

    return max(fmap[0][N - 1], gmap[0][N - 1]);
}

int main() {
    vector<int> arr = {3, 9, 1, 2};
    cout << win3(arr) << endl; // 示例输入,输出结果根据实际情况可能不同
    return 0;
}

 

 

 

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

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

相关文章

GiT: Towards Generalist Vision Transformer through Universal Language Interface

GiT: Towards Generalist Vision Transformer through Universal Language Interface 相关链接&#xff1a;arxiv github 关键字&#xff1a;Generalist Vision Transformer (GiT)、Universal Language Interface、Multi-task Learning、Zero-shot Transfer、Transformer 摘要 …

BigDecimal保留两位小数失败问题

文章目录 背景问题解决如何测试代码 背景 测试时发现在线swagger测试会自动处理BigDecimal小数点后面的数字&#xff0c;就是有零的会都给你去掉&#xff0c;比如9.000与9.500到最后都会被swagger处理成9跟9.5。使用postman测是最准的&#xff0c;测出来的就是9.000跟9.500。 …

Rocky Linux 基本工具的安装

1.系统安装后先查看ip地址 ip addr 2.安装net工具 &#xff1a;ifconfig yum install net-tools 3.安装gcc &#xff1b;选择都选 y yum install gcc yum install gcc-c 4.安装tcl yum install -y tcl 5.安装lsof &#xff08;端口查看工具&#xff09; yum install l…

MySQL实现事务隔离的秘诀之锁

在MySQL中&#xff0c;有多种锁类型&#xff0c;我们先了解三种概念的锁&#xff0c;以便对接下来的内容有更好理解。 表级锁&#xff08;Table Lock&#xff09;&#xff1a;对整个表加锁&#xff0c;其他事务无法修改或读取该表的数据&#xff0c;但可以对其他表进行操作。页…

SLAM 算法综述

LiDAR SLAM 其主要思想是通过两个算法&#xff1a;一个高频激光里程计进行低精度的运动估计&#xff0c;即使用激光雷达做里程计计算两次扫描之间的位姿变换&#xff1b;另一个是执行低频但是高精度的建图与校正里程计&#xff0c;利用多次扫描的结果构建地图&#xff0c;细化位…

切面条-蓝桥杯?-Lua 中文代码解题第1题

切面条-蓝桥杯&#xff1f;-Lua 中文代码解题第1题 一根高筋拉面&#xff0c;中间切一刀&#xff0c;可以得到2根面条。 如果先对折1次&#xff0c;中间切一刀&#xff0c;可以得到3根面条。 如果连续对折2次&#xff0c;中间切一刀&#xff0c;可以得到5根面条。 那么&#xf…

【QT入门】VS2019+QT的开发环境配置

声明&#xff1a;该专栏为本人学习Qt知识点时候的笔记汇总&#xff0c;希望能给初学的朋友们一点帮助(加油&#xff01;) 往期回顾&#xff1a; 【QT入门】什么是qt&#xff0c;发展历史&#xff0c;特征&#xff0c;应用&#xff0c;QtCreator-CSDN博客【QT入门】Windows平台下…

Java设计模式 | 设计模式概述和分类

独孤求败五重境界 利剑&#xff08;“凌厉刚猛&#xff0c;无坚不摧&#xff0c;弱冠前以之与河朔群雄争锋。”&#xff09;软剑&#xff08;“紫薇软剑&#xff0c;三十岁前所用&#xff0c;误伤义士不祥&#xff0c;乃弃之深谷。”&#xff09;重剑&#xff08;“重剑无锋&a…

React 实现下拉刷新效果

简介 本文基于react实现下拉刷新效果&#xff0c;在下拉的时候会进入loading状态。 实现效果 效果如上图所示&#xff0c;在下拉到底部时候&#xff0c;会出现loading条&#xff0c;在处理完成后loading条消失。 具体代码 布局 & 逻辑 import {useRef, useState} from …

【IC设计】Verilog线性序列机点灯案例(二)(小梅哥课程)

文章目录 该系列目录&#xff1a;设计目标设计思路RTL 及 Testbench仿真结果存在的问题&#xff1f;改善后的代码RTL代码testbench代码 仿真结果 案例和代码来自小梅哥课程&#xff0c;本人仅对知识点做做笔记&#xff0c;如有学习需要请支持官方正版。 该系列目录&#xff1a;…

javaEE——线程的等待和结束

文章目录 Thread 类及常见方法启动一个线程中断一个线程变量型中断调用 interrupt() 方法来通知观察标志位是否被清除 等待一个线程获取当前线程引用休眠当前线程 线程的状态观察线程的所有状态观察 1: 关注 NEW 、 RUNNABLE 、 TERMINATED 状态的切换 多线程带来的风险为什么会…

Ubuntu 14.04:安装 PaddleOCR 2.3

目录 一、说明 1.1 如何选择版本 1.2 查看 github 中的 PaddleOCR 版本 二、安装 2.1 安装前环境准备 2.2 下载包 2.3 解压 2.4 安装依赖库 异常处理&#xff1a;Read timed out. 2.5 下载推理模型&#xff1a;inference 2.5.1 模型存放位置 2.5.2 模型下载链接 2.5.…

【5G NB-IoT NTN】3GPP R17 NB-IoT NTN介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

​​SQLiteC/C++接口详细介绍之sqlite3类(十)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;九&#xff09; 下一篇&#xff1a;​​SQLiteC/C接口详细介绍之sqlite3类&#xff08;十一&#xff09; 30.sqlite3_enable_load_extension&#x…

Docker 学习笔记一

一、什么是docker Docker 是一个基于轻量级虚拟化技术的容器&#xff0c;整个项目基于Go语言开发&#xff1b;Docker是一个C/S架构&#xff0c;后端众多模块各司其职&#xff0c;docker的daemon是运行在主机上通过client可以进行通信。 docker 由三部分组成&#xff1a;镜像(…

读算法的陷阱:超级平台、算法垄断与场景欺骗笔记12_移动平台(上)

1. 广告 1.1. 广告收入的来源 1.1.1. 向客户推荐广告投放网址 1.1.2. 提供有效提高产品广告点击率的咨询服务 1.1.3. 从合作伙伴的广告收入中捞上一笔 1.2. 对于广告主来讲&#xff0c;他们无意于与各家网站逐一谈判 1.2.1. 这种方式一是成本过高&#xff0c;二是费时费力…

C#控制台贪吃蛇

Console.Write("");// 第一次生成食物位置 // 随机生成一个食物的位置 // 食物生成完成后判断食物生成的位置与现在的蛇的身体或者障碍物有冲突 // 食物的位置与蛇的身体或者障碍物冲突了&#xff0c;那么一直重新生成食物&#xff0c;直到生成不冲突…

算法——前缀和之除自身以外数组的乘积、和为K的子数组、和可被K整除的子数组、连续数组、矩阵区域和

这几道题对于我们前面讲过的一维、二维前缀和进行了运用,包含了面对特殊情况的反操作 目录 4.除自身以外数组的乘积 4.1解析 4.2题解 5.和为K的子数组 5.1解析 5.2题解 6.和可被K整除的子数组 6.1解析 6.2题解 7.连续数组 7.1题解 7.2题解 8.矩阵区域和 8.1解析 …

在pharmit里匹配药效团

我把400个无活性的小分子&#xff08;decoys&#xff09;提交到pharmit里。 命名为decoyset00~decoyset08&#xff0c;查找时&#xff0c;按这个找。 1、导入药效团配体&#xff1a; 进入药效团筛选界面&#xff1a; 导入代表药效团模型的活性肽构象&#xff1a; 2、选择预先…

搞机笔记 MI8 dipper

刷回MIUI 之前刷了 lineage-19.1-20220728-nightly-dipper-signed 基于安卓12&#xff0c;实现了以下功能 TWRPmagisk & ROOTmicroG 退回MIUI的原因有&#xff1a; lineage 墓碑 管不住APP后台&#xff0c;太卡了MIUI提供了3GB的虚拟内存lineage 不支持人脸识别lineag…