简单的动态规划题

上次课我们简单介绍了一下什么是动态规划,大家只要明白动态规划大致是什么就行了。
那么今天来干什么呢?
我们来看一道简单的题。
有人可能会惊了:什么?我还什么都不知道,怎么做题?
别急,有我在,我带着你做题,在做题中学习动态规划如何使用,一向崇尚“实践是检验真理的唯一标准!”
本人觉得讲太多的理论并没有什么鸟用。
所以我们来看题吧!

最大值(maximum)
现输入一个数列,求其中数的最大值。
输入格式:
第一行一个整数n表示数列的长度
第二行n个正整数,用一个空格隔开,表示数列中的每个数
输出格式:
一行一个整数
表示该数列中最大的一个数字。
输入样例1:
6
2 5 3 8 9 2
输出样例1:
9

很简单吧?
很明显我们有更多地更好地方法去做这个题,但是我们今天只看动态规划。
现在,我们想这样解题,我们依次求出前i个数中的最大值,然后得出结果。
那么我们如果不采取数组去记录,那么我们的复杂度是O(n^2)。
那么我们现在就设定一个数组f[]。
我们规定f[i]表示前i个数中最大的数。
那么我们的状态转移方程是什么呢?

f[i]=max(f[i-1],a[i]);

其中A数组存储原来数列的值。
那么这个方程是什么意思呢?
就是指前i个数中的最大值为前(i-1)个数的最大值与第i个数两者之间的最大值。
应该很好理解,这里把前i个数分为前(i-1)个数和第i个数两部分,那么总的部分的最大值应该是两个小部分的最大值。
这样我们的状态转移方程就写好了。

为什么要叫作状态转移方程?
因为这是两个状态之间的转换用到的方程式,所以我们称之为状态转移方程。

这两方面考虑好后,我们就能很轻易地写出程序:

#include<bits/stdc++.h>
using namespace std;
int f[10000005];
int a[10000005];
int n;
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    f[0]=0;
    for(int i=1;i<=n;i++){
        f[i]=max(f[i-1],a[i]);
    }
    printf("%d",f[n]);
    return 0;
}

那么这道题目就做了了。
现在,让我们再来回顾我们做题目的过程,我们其实主要就干了两件事。
那就是:设计状态和状态转移方程。

所谓设计状态,就是指设计数组(记录最优值的数组)的过程。
所谓状态转移方程,就是咱们前面介绍的,这里不再赘述。

其实我们做动态规划的题,最重要的就是这两步(当然除了一步最最重要的——看出来这道题要用动他规划。某位长者说过:“当你看出来一道题要用动态规划,那么这道题你就已经做了50%”)。

所以在我们发现这道题是动态规划以后,那么我们思考的核心就是这两样东西。

所以在以后的做题的时候我们会围绕这两方面做详细阐释。

这一节就到这。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值