(经典dp) hdu 递推求解专题练习

news2025/1/9 23:34:18

文章目录

  • 前言
  • 题单
    • hdu2044 一只小蜜蜂...
    • hdu2045 不容易系列之(3)—— LELE的RPG难题
    • hdu2046 骨牌铺方格
    • hdu2047 阿牛的EOF牛肉串
    • hdu2048 神、上帝以及老天爷
    • hdu2049 不容易系列之(4)——考新郎
    • hdu2050 折线分割平面
  • END

前言

题单:递推求解专题练习(For Beginner)

这是(hdu.edu.cn) 一份非常经典的dp递推求解的题单

起始本质是一堆线性dp

虽说是For Beginner,但博主做的时候还是吃了很多憋的

可能博主还处于beginner的阶段吧


下文中题意直接略

题单

hdu2044 一只小蜜蜂…

hdu2044 一只小蜜蜂…

观察到每个点只有由左侧相邻的两个点转换而来

这两个点分别为x-1x-2

C40-1001-1.jpg (422×97) (hdu.edu.cn)

从起点到终点

/**
 * https://acm.hdu.edu.cn/showproblem.php?pid=2044
 * 一只小蜜蜂...
 * 斐波那契数列变体
 */
#include <bits/stdc++.h>
using namespace std;

void solve() {
    int x, y;
    cin >> x >> y;

    vector<long long> dp(y + 1);
    dp[x] = 1;
    dp[x + 1] = 1;
    for (int i = x + 2; i <= y; i++) {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    cout << dp[y] << endl;
}

int main() {
    int x = 1;
    cin >> x;

    while (x--) {
        solve();
    }

    return 0;
}

打表+偏移量

/**
 * https://acm.hdu.edu.cn/showproblem.php?pid=2044
 * 一只小蜜蜂...
 * 斐波那契数列变体
 */
#include <bits/stdc++.h>
using namespace std;

int main() {
    vector<long long> dp(50 + 1);
    dp[1] = 1;
    dp[2] = 1;
    for (int i = 3; i < dp.size(); i++) {
        dp[i] = dp[i - 1] + dp[i - 2];
    }

    int T = 1;
    cin >> T;

    while (T--) {
        int x, y;
        cin >> x >> y;
        cout << dp[y - x + 1] << endl;
    }

    return 0;
}

hdu2045 不容易系列之(3)—— LELE的RPG难题

hdu2045 不容易系列之(3)—— LELE的RPG难题

类似的思考方式的题

专题:(经典dp) I型 L型 铺盖2*n_天赐细莲的博客-CSDN博客

一道很不错的线性dp推到题

限制了两个条件

  1. 相邻状态不能相同
  2. 不能和首位置相同

线性dp

从尾位置开始往前推导

/**
 * https://acm.hdu.edu.cn/showproblem.php?pid=2045
 * 不容易系列之(3)—— LELE的RPG难题
 */
#include <bits/stdc++.h>
using namespace std;
#define int long long

const int M = 10 + 50;
// 定义第i位的可能情况
int dp[M];

int __init__ = []() {
    // 根据下面的推到,要求dp[i-2]
    // 因此手动推到出前三项
    dp[1] = 3;
    dp[2] = 6;
    dp[3] = 6;

    // 考虑第i个位置
    // 1. 若i-1与1不同 则i确定 dp[i-1]
    // 2. 若i-1与1相同 则i与i-1不同的两种 理想状态是 2*dp[i-1]
    // 但这个dp[i-1]的i-1位是记录与1不同的
    // 因此直接考虑,i-1位和1相同的情况
    // 显然确定了一个颜色后,前面只能放另外2种 => dp[i-2]*2
    // 综上:dp[i] = dp[i-1] + 2 * dp[i-2]
    for (int i = 4; i < M; i += 1) {
        dp[i] = dp[i - 1] + 2 * dp[i - 2];
    }
    return 0;
}();

signed main() {
    int n;
    while (cin >> n) {
        cout << dp[n] << endl;
    }
    return 0;
}

状态机dp

全网大都是线性dp的思路,但这个也是典型的状态机dp的题


我一开始定义的状态机为dp[i][j] 直接考虑到第i个位置,填颜色j的种类总数

但是这么定义死活不能ac,因为相邻是好推导的,难点在于如何考虑首尾不同这个限制

本来想再加一个维度表示相同和不同,但是还是没写出来


最后再搜了大量博客后终于找到了一篇,定义的含义为**针对起始的一种颜色**,末尾放三种的可能性

最后只要*3即可,豁然开朗

/**
 * https://acm.hdu.edu.cn/showproblem.php?pid=2045
 * 不容易系列之(3)—— LELE的RPG难题
 * ==============================================
 * 状态机dp
 * 增加一个维度表示末尾放到是什么颜色
 */
#include <bits/stdc++.h>
using namespace std;
#define int long long

const int M = 10 + 50;
// 定义dp[i][3]
// **针对起始的一种颜色**,末尾放三种的可能性
int dp[M][3];

int __init__ = []() {
    // 假设考虑的颜色为0号
    dp[1][0] = 1;
    dp[1][1] = 0;
    dp[1][2] = 0;
    for (int i = 2; i < M; i += 1) {
        // 相邻的颜色不同
        dp[i][0] = dp[i - 1][1] + dp[i - 1][2];
        dp[i][1] = dp[i - 1][0] + dp[i - 1][2];
        dp[i][2] = dp[i - 1][0] + dp[i - 1][1];
    }
    return 0;
}();

signed main() {
    int n;
    while (cin >> n) {
        if (n == 1) {
            // n=1特判
            // 因为n为1时,首位和末尾是相同的
            cout << 3 << endl;
        } else {
            // 三种颜色 *3
            // 计算时,假设的起始颜色为0,则末尾不算0的情况
            cout << (dp[n][1] + dp[n][2]) * 3 << endl;
        }
    }

    return 0;
}

hdu2046 骨牌铺方格

hdu2046 骨牌铺方格

专题:(经典dp) 骨牌问题 2n 3n n*m_天赐细莲的博客-CSDN博客

C40-1003-1.jpg (589×344) (hdu.edu.cn)

太经典了,这个问题

  • 假设最后一个块竖着放,则由dp[i-1]推导来

  • 假设最后一个块横着放,则必须两个块一起横着放,由dp[i-2]推导来

/**
 * 专题博客:https://blog.csdn.net/CUBE_lotus/article/details/127895641
 * https://acm.hdu.edu.cn/showproblem.php?pid=2046
 * 骨牌铺方格
 */
#include <bits/stdc++.h>
using namespace std;
#define int long long

const int M = 10 + 50;

int dp[M];

int __init__ = []() {
    dp[1] = 1;
    dp[2] = 2;
    for (int i = 3; i < M; i += 1) {
        dp[i] = dp[i - 1] + dp[i - 2];
    }

    return 0;
}();

signed main() {
    int n;
    while (cin >> n) {
        cout << dp[n] << endl;
    }
    return 0;
}

hdu2047 阿牛的EOF牛肉串

hdu2047 阿牛的EOF牛肉串

也是一道经典的状态机dp,难度限制只有相邻的状态

把状态值定义在第一维的一个好处

可以便捷初始化这个状态的所有值 memset(dp[state], 0, sizeof(dp[state]))

/**
 * https://acm.hdu.edu.cn/showproblem.php?pid=2047
 * 阿牛的EOF牛肉串
 * 以后缀分析问题
 */
#include <bits/stdc++.h>
using namespace std;
#define int long long
// 长度40了,记得开long long
int dp[3][40 + 1];
signed main() {
    dp[0][1] = 1;
    dp[1][1] = 1;
    dp[2][1] = 1;

    for (int i = 2; i <= 40; i++) {
        dp[0][i] = dp[0][i - 1] + dp[1][i - 1] + dp[2][i - 1];
        dp[1][i] = dp[0][i - 1] + dp[1][i - 1] + dp[2][i - 1];
        dp[2][i] = dp[0][i - 1] + dp[1][i - 1];
    }

    int n;
    while (cin >> n) {
        cout << dp[0][n] + dp[1][n] + dp[2][n] << endl;
    }

    return 0;
}

hdu2048 神、上帝以及老天爷

hdu2048 神、上帝以及老天爷

概率相关的题我直接跪

参考博客:[航电ACM hdu-2048] 神、上帝以及老天爷_Litmmp的博客-CSDN博客

了解到了这个错排公式

错排公式_百度百科

/**
 * https://acm.hdu.edu.cn/showproblem.php?pid=2048
 * 神、上帝以及老天爷
 * ==============================================
 * 求没人中将的百分比
 * ==============================================
 * 参考博客:
 * https://blog.csdn.net/u011506951/article/details/25157161
 */
#include <bits/stdc++.h>
using namespace std;

const int M = 10 + 20;
double dp[M];

int __init__ = []() {
    // 求分母,即 n!
    double denominator[M];
    denominator[1] = 1.0;
    for (int i = 2; i < M; i += 1) {
        denominator[i] = denominator[i - 1] * i;
    }

    // 分子
    /*
    dp[] 表示考虑到i个人都是错态的种类
    若i拿了自己的票,则与i-1人交换即可
    (i-1)*dp[i-1]

    若i-1人中有人拿了自己的票,则无论i拿的是不是,只要和那个拿了自己票的交换即可
    i-1中除去拿自己票的有i-2人
    (i-1)*dp[i-2]
    */
    double molecule[M];
    molecule[1] = 0;
    molecule[2] = 1;
    for (int i = 3; i < M; i += 1) {
        molecule[i] = (i - 1) * (molecule[i - 1] + molecule[i - 2]);
    }

    for (int i = 1; i < M; i += 1) {
        dp[i] = molecule[i] / denominator[i];
    }
    return 0;
}();

signed main() {
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        printf("%.2lf%%\n", dp[n] * 100);
    }
    return 0;
}

hdu2049 不容易系列之(4)——考新郎

hdu2049 不容易系列之(4)——考新郎

错排公式_百度百科

组合数_百度百科

错排公式+组合数

/**
 * https://acm.hdu.edu.cn/showproblem.php?pid=2049
 * 不容易系列之(4)——考新郎
 * ===============================================
 * N对新婚夫妇,其中有M个新郎找错了新娘
 * 求发生这种情况一共有多少种可能
 * 错态 * 组合
 */
#include <bits/stdc++.h>
using namespace std;
#define int long long

const int M = 10 + 20;
// 表示前i个数的错态种类(位置全不对)
int dp[M];

int __init__ = []() {
    dp[1] = 0;
    dp[2] = 1;
    for (int i = 3; i < M; i++) {
        dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]);
    }

    return true;
}();

// 组合数公式
// n个数中取m个求组合数
inline int Combination(int m, int n) {
    int ans = (m <= n);
    m = min(m, n - m);
    for (int i = 0; i < m; i++) {
        ans *= n - i;
    }
    for (int i = 1; i <= m; i++) {
        ans /= i;
    }
    return ans;
}

signed main() {
    int T, n, m;
    cin >> T;
    while (T--) {
        cin >> n >> m;
        // 错态*组合
        cout << dp[m] * Combination(m, n) << endl;
    }

    return 0;
}

排列组合公式

排列组合 百度百科

排列

A n m = n ( n − 1 ) ( n − 2 ) ⋅ ⋅ ⋅ ( n − m + 1 ) = n ! ( n − m ) ! 共 m 个 因 子 累 乘 n > = m A^{m}_{n} = n(n-1)(n-2)···(n-m+1) = {n!\over(n-m)!} \\[2ex] 共m个因子累乘\quad n >= m Anm=n(n1)(n2)(nm+1)=(nm)!n!mn>=m


组合
C n m = A n m m ! = n ! m ! ( n − m ) ! C n m = C n n − m n > = m C^{m}_{n} = {A^{m}_{n}\over {m!}} = {n!\over {m!(n-m)!}} \\[2ex] C^{m}_{n} = C^{n-m}_{n} \qquad n >= m Cnm=m!Anm=m!(nm)!n!Cnm=Cnnmn>=m


计算举例:

举 例 C 5 3 = C 5 2 计 算 5 ∗ 4 ∗ 3 3 ∗ 2 ∗ 1 = 5 ∗ 4 2 ∗ 1 分 子 分 母 各 m 个 数 累 乘 C 5 3 = 5 ∗ ( 5 − 1 ) ∗ ( 5 − 2 ) 1 ∗ 2 ∗ 3 举例 \qquad \qquad C^{3}_{5} = C^{2}_{5} \\[2ex] 计算 \qquad \qquad {5*4*3 \over 3*2*1} = {5*4 \over 2*1} \qquad 分子分母各m个数累乘 \\[2ex] C^{3}_{5} = {5*(5-1)*(5-2) \over 1*2*3} C53=C52321543=2154mC53=1235(51)(52)


问题举例:

有1个A,2个B,3个C 共有多少种排列
6 ! 1 ! ∗ 2 ! ∗ 3 ! {6!\over 1! * 2! * 3!} 1!2!3!6!

// n个中选m个
inline int Combination(int m, int n) {
    int ans = (m <= n);
    m = min(m, n - m);
    for (int i = 0; i < m; i++) {
        ans *= n - i;
    }
    for (int i = 1; i <= m; i++) {
        ans /= i;
    }
    return ans;
}

hdu2050 折线分割平面

hdu2050 折线分割平面

C40-1008-1.jpg (613×345) (hdu.edu.cn)

画图分析,有多少个折线的焦点

/**
 * https://acm.hdu.edu.cn/showproblem.php?pid=2050
 * 折线分割平面
 */
#include <bits/stdc++.h>
using namespace std;

int main() {
    vector<long long> dp(10000 + 10);
    dp[1] = 2;
    for (int i = 2; i < dp.size(); i++) {
        // 首先获取上一轮的值
        // 再计算,与之前的每一条线都有4个焦点,每个焦点贡献出一块区域
        // 最后自己的小尖角
        dp[i] = dp[i - 1] + 4 * (i - 1) + 1;
    }

    int T = 1;
    cin >> T;

    while (T--) {
        int x;
        cin >> x;
        cout << dp[x] << endl;
    }

    return 0;
}



END

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

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

相关文章

华为机试 - 找出经过特定点的路径长度

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 无 输入描述 输入一个字符串&#xff0c;都是以大写字母组成&#xff0c;每个相邻的距离是 1&#xff0c; 第二行输入一个字符串&#xff0c;表示必过的点。 说明每个点可过多次。 输出描述 经过这…

精益(Lean)与ERP实施

周四、五看完了24小时不停的Lean Global Connection&#xff0c;总觉得要说些什么。 印象最深的有三个地方&#xff1a; 一是John Shook的话&#xff0c;他说Lean是一种Mindset。 这种Mindset是&#xff1a; 一种积极的态度&#xff0c;Problems solving, 把问题和挑战当成是…

Web 性能优化:TLS

个人博客 Web 性能优化&#xff1a;TCP&#x1f3af; Web 性能优化&#xff1a;TLSWeb 性能优化&#xff1a;HTTP “do it, do it work, do it better … and secure ☠️” 随着追逐利益而来的恶意参与者越来越多&#xff0c;当前的 Web 应用&#xff0c;已经从野蛮生长转而…

【通关MySQL】Java的JDBC编程

✨哈喽&#xff0c;进来的小伙伴们&#xff0c;你们好耶&#xff01;✨ &#x1f6f0;️&#x1f6f0;️系列专栏:【通关MySQL】 ✈️✈️本篇内容:Java的JDBC编程。 &#x1f680;&#x1f680;代码存放仓库gitee&#xff1a;MySQL码云存放&#xff01; ⛵⛵作者简介&#xff…

[附源码]java毕业设计-室内田径馆预约管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

轻量应用服务器和云服务器CVM有什么区别?

腾讯云新推出的轻量应用服务器Lighthouse和原来的CVM云服务器有什么区别&#xff1f;轻量应用服务器Lighthouse是一种易于使用和管理、适合承载轻量级业务负载的云服务器&#xff0c;主要用于Web网站应用&#xff0c;轻量服务器使用及后期运维更加简单方便&#xff1b;云服务器…

RNA-seq 保姆教程:差异表达分析(二)

介绍 RNA-seq 目前是测量细胞反应的最突出的方法之一。RNA-seq 不仅能够分析样本之间基因表达的差异&#xff0c;还可以发现新的亚型并分析 SNP 变异。本教程[1]将涵盖处理和分析差异基因表达数据的基本工作流程&#xff0c;旨在提供设置环境和运行比对工具的通用方法。由于完整…

计算机网络——数据链路层

数据链路层概述 数据链路层在网络体系结构中所处的地位 主机H1给主机H2发送数据时&#xff0c;需要通过路由器R1通过广域网链路转发到路由器R2&#xff0c;R2转发到主机H2。路由器转发只用到网络层及以下各层。【以上涉及数据包按网络体系结果逐层封装解封】 为了简单起见&am…

DevC++的调试方法

目录 Dev C调试程序 Dev C调试注意事项对于修改后的程序&#xff0c;调试程序之前一定要先编译程序。 要想学会编程,第一步就是要学会调试(想我这种码龄一年的人还不会调试,丢死人). 今天,为了让你们的脸丢少点,特意写了这篇博文,给予需要帮助的人. 所谓调试程序&#xff0…

[附源码]计算机毕业设计JAVA基于JSP健身房管理系统

[附源码]计算机毕业设计JAVA基于JSP健身房管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM m…

Python实现KNN(K近邻)分类模型(KNeighborsClassifier算法)并应用网格搜索算法寻找最优参数值以及数据标准化均衡化项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 股票市场是已经发行的股票转让、买卖和流通的场所&#xff0c;包括交易所市场和场外交易市场两大类别。…

【C++】C++11部分特性

目录 一、初始化列表 二、变量类型的推导 1、auto 2、decltype 三、右值引用 1、左值与右值 2、关于左值引用、右值引用的问题 1、左值引用可以引用右值吗&#xff1f; 2、右值引用可以引用左值吗&#xff1f; 3、右值引用之后的问题 3、移动构造、移动拷贝 1、引用…

软件测试质量保证与测试

软件测试质量保证与测试 第一章 软件测试概述 1.1 软件测试背景 随着计算机技术的迅速发展和越来越广泛深入地应用于国民经济与社会生活的各个方面&#xff0c;软件系统的规模和复杂性与日俱增&#xff0c;软件的生产成本和软件中存在的缺陷与故障造成的各类损失也大大增加&…

【应用】PostgreSQL 流复制配置

PostgreSQL 流复制配置centos7 安装 postgresql时序库 timescaleDB 的安装postgresql-14 主从流复制主库配置从库配置同步流复制与异步流复制异步流复制转换为同步流复制流复制的相关参数主从流复制原理PostgreSQL WAL 日志主从流复制架构主从流复制的过程基于 docker swarm 的…

CMSC5713-IT项目管理之七、质量管理Quality Management

文章目录7.1 Quality7.2. Software Quality7.2.1. ISO/IEC 25010 Software Qualities7.2.2. Internal versus External qualities7.2.3. Software Metrics7.3. Quality Specification7.4. Project Quality Management7.4.1. Quality Planning7.4.2. Quality Assurance7.4.2.1. …

vscode 阅读 linux kernel 源码

前言 虽然身边的朋友大都在使用 source insight&#xff0c;但我却更喜欢 vscode。 不过 vscode 在代码搜索上确实不如 source insight&#xff0c;这点上我也是吃过亏的。阅读大型代码时&#xff0c;常常搜索不到关键代码&#xff0c;导致对代码的理解不充分。 当使用 vscode…

Java-反射

前言 动态语言与静态语言 动态语言 是一类在运行时可以改变其结构的语言&#xff1a;例如新的函数、对象、甚至代码可以被引进&#xff0c;已有的函数可以被删除或是其他结构上的变化。通俗点说就是在运行时代码可以根据某些条件改变自身结构主要动态语言有&#xff1a;Object…

【开源电路】STM32F401RCT6开发板

【开源电路】STM32F401RCT6开发板&#x1f337;实物PCBA&#xff1a; &#x1f33c;优化后的3D效果图 &#x1f4da;STM32F401RCT6开发板简介 &#x1f4d1;主控是LQFP-64封装的STM32F401RCT6芯片&#xff0c;Micro USB接口供电&#xff0c;功能引脚全部引出&#xff0c;一个…

金融强化学习与finRL开发包

原创文章第110篇&#xff0c;专注“个人成长与财富自由、世界运作的逻辑&#xff0c; AI量化投资”。 01 一些感受 时代的一粒沙&#xff0c;落在每个人身上就是一座山。 这三年&#xff0c;对于这句话&#xff0c;相信很多人更能感同身受。 看历史风云变幻&#xff0c;轻轻…

力扣(LeetCode)21. 合并两个有序链表(C++)

迭代 同时遍历两个链表 &#xff0c; 当前结点值较小的结点插入新的链表尾部。直到有一个链表为空 &#xff0c; 我们将另一个非空链表插入新的链表尾部。 提示 : 使用哑结点&#xff0c;避免特判头结点。二路归并思想应用于链表~ class Solution { public:ListNode* mergeT…