动态规划(1)

来源:互联网 发布:grub引导linux 编辑:程序博客网 时间:2024/06/07 02:18

使用动态规划求解问题,最重要的就是确定动态规划三要素:
(1)问题的阶段 (2)每个阶段的状态
(3)从前一个阶段转化到后一个阶段之间的递推关系。
递推关系必须是从次小的问题开始到较大的问题之间的转化,从这个角度来说,动态规划往往可以用递归程序来实现,不过因为递推可以充分利用前面保存的子问题的解来减少重复计算,所以对于大规模问题来说,有递归不可比拟的优势,这也是动态规划算法的核心之处。
确定了动态规划的这三要素,整个求解过程就可以用一个最优决策表来描述,最优决策表是一个二维表,其中行表示决策的阶段,列表示问题状态,表格需要填写的数据一般对应此问题的在某个阶段某个状态下的最优值(如最短路径,最长公共子序列,最大价值等),填表的过程就是根据递推关系,从1行1列开始,以行或者列优先的顺序,依次填写表格,最后根据整个表格的数据通过简单的取舍或者运算求得问题的最优解。
f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}


给定一个非负整数数组,假定你的初始位置为数组第一个下标。

数组中的每个元素代表你在那个位置能够跳跃的最大长度。

你的目标是到达最后一个下标,并且使用最少的跳跃次数。

例如:

A=[2,3,1,1,4],到达最后一个下标的最少跳跃次数为 22。(先跳跃 11 步,从下标 00 到 11,然后跳跃 33 步,到达最后一个下标。一共两次)

输入格式

第一行输入一个正整数 n(1 \le n \le 100)n(1≤n≤100) ,接下来的一行,输入 nn 个整数,表示数组 AA。

输出格式

最后输出最少的跳跃次数。

样例输入

5
3 1 1 1 1
样例输出

2


分析题目:
针对例子 2 3 1 1 4
问题的阶段:
走到第几格,表示一个阶段,这里共有5个阶段
用d[i]表示各个阶段,首先第一阶段为d[0] = 0(0表示不用走,0步);
每个阶段的状态:
d[0] = 0
d[1] = d[0]+1(条件为2>1-0;);
d[2] = min{d[0]+1,d[1]+1};
d[3] = min{d[1]+1,d[2]+1};
……….
从前一个阶段转化到后一个阶段之间的递推关系:
d[i] = min{d[j]+1};为最后的状态转移方程式


#include<iostream>#include<vector>#include<cstring>#define MAX 0X3F3F3F3F using namespace std;int main(){    int n, d[100];    memset(d,MAX,sizeof(d));    d[0] = 0;//初始状态    vector<int> ve;    cin >> n;    for(int i = 0; i < n; i++)    {        int temp;        cin >> temp;        ve.push_back(temp);    }    for(int i = 1; i < n; i++)    {        for(int j = 0; j <= i; j++)        {            if(i-j <= ve[j]&&d[j]+1<d[i])//动态规划转换方程             {                d[i] = d[j] + 1;            }        }    }    cout << d[n-1];    return 0;}
0 0