【课程】算法设计与分析——第八周 题解笔记

这篇具有很好参考价值的文章主要介绍了【课程】算法设计与分析——第八周 题解笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第八周 算法题解笔记

1极值点

题目描述

  • 给定一个单峰函数f(x)和它的定义域,求它的极值点
  • 该单峰函数f(x)保证定义域内有且只有一个极值点,且为极大值点

题解

本题感觉和dp关系不大,主要思路是三分法,和二分法非常类似,但没有二分法常用,主要用途是用来求单峰函数的极值

  1. 对于任意一个上凸函数,选取函数上任意两个点A,B(xA<xB),

    若满足yA<yB,那么该函数的极值点必然在[xA,+∞)中,

    若满足yA>yB,那么该函数极值点必然在(-∞,xB]中,

    若满足yA=yB,那么该函数的极值点必然在[xA,xB]中。

  2. 对于任意一个下凸函数,选取函数上任意两个点A,B(xA<xB),

    若满足yA<yB,那么该函数的极值点必然在(-∞,xB]中,

    若满足yA>yB,那么该函数极值点必然在[xA,+∞)中,

    若满足yA=yB,那么该函数的极值点必然在[xA,xB]中。

代码

void Solve(){
    double left, right, m1, m2, m1_value, m2_value;
    left = MIN;
    right = MAX;
    while (left + EPS < right){
        m1 = left + (right - left)/3;
        m2 = right - (right - left)/3;
        m1_value = f(m1);
        m2_value = f(m2);
        if (m1_value >= m2_value)
            right = m2;  //假设求解极大值
        else  left = m1; 
    }
}

2 硬币问题

https://vjudge.net/problem/洛谷-B3635

题目描述

  • 今有面值为 1、5、11 元的硬币各无限枚。
  • 想要凑出 n 元,问需要的最少硬币数量。

题解

本题是dp的入门题,和背包问题很像,但硬币问题更简单一些,只需要1维的数组就可以表示

解决dp问题一般需要4步:

  1. 确定状态:定义状态,比如f[i]f[i][j] 代表什么

    我自己每次做dp的时候都会卡在写状态转移方程那步,后来才发现困难的原因在于第一步定义状态就没有做好,从没深入思考过这样定义状态的原因是什么,自然写状态转移方程就会出错或者写不出来

    确定状态往往需要思考两个问题:

    • 如何定义最后一步
    • 如何划分子问题
  2. 写状态转移方程:

    当我认真思考上面两个问题之后,状态转移方程就非常容易理解了,根据子问题的问题定义就可以得到

  3. 确定初始条件和边界

  4. 确定计算顺序

接下来根据这4步分析硬币问题

  1. 确定状态

    • 最后一步

      假设最后一枚硬币的面值为k,支付n元最少需要的硬币总数可以被表示为:支付n-k元最少需要的硬币数+1(最后一枚)

    • 划分子问题

      原问题:支付n元最少需要多少枚硬币

      子问题:支付n-k元最少需要多少枚硬币
      因此定义状态为f[i] ,表示支付i元最少需要f[i]枚硬币

  2. 写状态转移方程

    每次状态转换都有三种选择,用1元硬币、用5元硬币和用11元硬币

    \[f[i]=min \begin{cases} f[i-1]+1& {i\geq 1}\\ f[i-5]+1& {i\geq 5}\\ f[i-11]+1& {i\geq 11} \end{cases}=min(f[i-1],f[i-5],f[i-11])+1 \]
  3. 确定初始条件和边界

    f[0]=0 :0元需要0枚硬币

    在进行状态转移的时候需要进行判断,需要支付的金额不能比硬币面值小,否则会变成负值

    另外由于本题有1元硬币,所以不存在所有硬币都无法支付的情况

  4. 确定计算顺序

    升序计算,当计算f[i]的时候,需要f[i-1]f[i-5]f[i-11]的值

至此,分析结束,下面是代码

代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

int maxn = 10e7;

int f[1000005];

int main()
{
    int n;
    cin>>n;
    f[0]=0;

    for(int i=1;i<=n;i++){
        f[i] = maxn;
        if(i>=1){
            f[i]=min(f[i], f[i-1]+1);
        }
        if(i>=5){
            f[i]=min(f[i], f[i-5]+1);
        }
        if(i>=11){
            f[i]=min(f[i],f[i-11]+1);
        }
    }
    cout<<f[n]<<endl;
    return 0;
}

ac截图

【课程】算法设计与分析——第八周 题解笔记

3 数塔问题

https://vjudge.net/problem/51Nod-2073

题目描述

有如图所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?

【课程】算法设计与分析——第八周 题解笔记

题解

为了方便表述,我们默认层数从1开始,而不是0

  1. 确定状态

    数塔权值表示:w[i][j]

    • 最后一步

      假设数塔共n层,走到最后一层的第j个结点时,最大数字之和可以被表示为:经过左上和右上两条路径的最大数字之和+w[n][j]

    • 划分子问题

      原问题:1-n层的最大数字之和

      子问题:1-(n-1)层的最大数字之和
      因此状态定义为f[i][j],表示走到第i层第j个结点时的最大数字之和

  2. 写状态转移方程

    \[f[i][j]=max(f[i-1][j-1],f[i-1][j])+w[i][j] \]
  3. 确定初始条件和边界

    f[0]=0:0层的数字之和为0

    对于最左边一列的结点w[i][0],只有一个父节点w[i][0],需要注意判断i-1是否为负数的情况

  4. 确定计算顺序

    升序计算,当计算f[i][j]的值时,需要f[i-1][j-1]f[i-1][j]的值

代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

int f[105][105];
int w[105][105];

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=0;j<i;j++){
            cin>>w[i][j];
        }
    }
    for(int i=0;i<=n;i++){
        for(int j=0;j<=n;j++){
            f[i][j]=0;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<i;j++){
            if(j==0){
                f[i][j]=f[i-1][j]+w[i][j];
            }
            else{
                f[i][j]=max(f[i-1][j-1],f[i-1][j])+w[i][j];
            }
        }
    }
    int ans=0;
    for(int j=0;j<n;j++){
        ans=max(ans,f[n][j]);
    }
    cout<<ans<<endl;
    return 0;
}

ac截图

【课程】算法设计与分析——第八周 题解笔记

4 小美的数组构造

https://www.nowcoder.com/questionTerminal/5ff1c46cc9814c65850bbdabe47e8fbb

题目描述

题目有点长就不复制粘贴了

题解

可以把题目看成总和为m划分成n个数字,且每个数字都和数组a不一样的方案数,可以用dp来解

PS:网上似乎也有差分的思路,之后来学习一下,写在下次笔记里

  1. 确定状态

    • 最后一步

      假设构造一个数组b,总和为m,长度为n

      最后一步应是数组b已经构造了n-1个数字,总和为m-b[n],b[n]≠a[n]的方案数

    • 划分子问题

      原问题:构造长度n总和m且数字和数组a不一样的数组的方案数

      子问题:构造长度n-1总和m-b[n]且数字和数组a不一样的子数组的方案数
      因此定义状态为f[i][j],表示前i个数和为j的方案数

  2. 写状态转移方程

    \[f[i][j]=\Sigma _{k=1}^{j}f[i-1][k] \]
  3. 确定初始条件和边界

    f[0][0]=1

    需要注意k≠a[i],题目要求

  4. 确定计算顺序

    根据状态转移方程可以看出是升序计算

代码

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll a[500], f[305][505], m;
int mod=1e9+7;
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        m+=a[i];
    }
    f[0][0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            for(int k=1;k<=j;k++)
                if(k!=a[i])
                    f[i][j]=(f[i][j]+f[i-1][j-k])%mod;
        }
    }
    cout<<f[n][m]<<endl;
    return 0;
}

ac截图

【课程】算法设计与分析——第八周 题解笔记文章来源地址https://www.toymoban.com/news/detail-746190.html

到了这里,关于【课程】算法设计与分析——第八周 题解笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【算法分析与设计】第八章-回溯法

    约束条件 分为 显式约束 和 隐式约束 显式:规定了问题的解的分量的取值范围。如求n的全排列每个位置只能取1~n 隐式:用于判定候选解是否为可行解。如全排列的每个数字不允许重复。 问题状态和状态空间树         状态空间树是 描述问题解空间 的树形结构,每个结

    2024年02月08日
    浏览(35)
  • 浙大数据结构第八周之08-图7 公路村村通

    现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。 输入格式: 输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路

    2024年02月11日
    浏览(23)
  • Go-Python-Java-C-LeetCode高分解法-第八周合集

    本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接:LeetCode-Go-Python-Java-C 欢迎订阅CSDN专栏,每日一题,和博主一起进步 LeetCode专栏 我搜集到了50道精选题,适合速成概览大部分常用算法 突破算法迷宫:精选50道-算法刷题指南 本文部分内容来自网上

    2024年02月07日
    浏览(32)
  • 《数据结构与算法分析》课程设计——迷宫问题

    中国矿业大学信控学院   补一下我之前在博客园发布的内容  懒得调了, 想复制完整代码直接复制最下面的 ,想复制分布代码去看我博客园链接吧 《数据结构与算法分析》课程设计——迷宫问题 - 刷子zz - 博客园 一、  问题描述 问题中迷宫可用方阵[m,n]表示,0表示能通过

    2024年02月10日
    浏览(33)
  • 【算法设计与分析】回溯法解决运动员配对问题(课程设计)

    针对运动员最佳配对问题,本文利用回溯法寻求竞赛优势得分最优解,研究男女运动员最佳配对法,使各组男女双方竞赛优势的总和达到最大。针对这一问题,本题采用的是男运动员选女运动员的方法,构成了一棵排列树。树的结点表示女运动员,排列树的层数表示男运动员

    2024年02月10日
    浏览(55)
  • 《算法分析与设计》复习笔记

    目录 一、算法的基本概念 1.1 算法的定义 1.2 算法的“好坏”如何衡量? 1.3 描述算法的时间复杂度 ⭐ 1.4 如何评价算法 二、 分治法 2.1 分治法的求解步骤 2.2 平衡的概念 2.3 递归式解法 2.3.1 主定理法 ⭐ 2.4 分治法的使用条件 2.5 分治法实例 2.5.1 快速排序 2.5.2 最大元最小元问

    2024年02月03日
    浏览(27)
  • 算法设计与分析学习笔记之二分查找算法

    二分查找只适用于有序的顺序表,非严格递增或是非严格递减都行。 二分查找运用到了分治的思想,将整体逐渐分为许多个小的部分,让整体的解变为诸多小部分解的合成,要求整体可以分解,小部分的解汇合之后可以得到整体部分的解。 至此,结束。 如果你觉得这篇文章

    2024年02月09日
    浏览(34)
  • 【笔记】【算法设计与分析 - 北航童咏昕教授】绪论

    算法设计与分析 - 北航童咏昕教授 定义 给定计算问题,算法是一系列良定义的计算步骤,逐一执行计算步骤即可得预期的输出。 性质 有穷性 确定性 可行性 自然语言 方法优势 贴近人类思维,易于理解主旨 不便之处 语言描述繁琐,容易产生歧义 使用了“…”等不严谨的描

    2024年02月22日
    浏览(25)
  • 算法设计与分析复习笔记第六章分支限界法

    分支限界法的基本思想 分支限界法类似于回溯法,也是一种在问题的解空间树T中搜索问题解的算法。 但在一般情况下,分枝限界法与回溯法的求解目标不同。回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分枝限界法的求解目标则是找出满足约束条件的一个

    2024年02月03日
    浏览(34)
  • 嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第八天-Linux sqlite3数据库(物联技术666)

       更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客 物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件

    2024年01月25日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包