动态规划(一)

来源:互联网 发布:绝地求生画面优化教程 编辑:程序博客网 时间:2024/06/07 16:50

动态规划与分治方法相似,都是通过组合子问题的解来求原问题。
(分治方法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归求解这些子问题,然后在合并这些子问题的解来建立原问题的解)
动态规划通常用来求解最优解的问题、其是付出额外的内存空间来节省计算时间,典型的时空权衡(time-memory)的例子。
动态规划有两种等价实现方式:
(一)带备忘的自顶向下法。这是按照自然递归的方法编写,但过程中会保存每个子问题的解(通常保存在数组和散列表中)。
(二)自底向上法。这种方法需要定义恰当子问题“规模”概念。使得任何子问题的求解都只依赖鱼更小的额子问题的求解。因而我们可以将子问题的规模排序,由小至大的顺序进行求解。

有关动态规划的解题
HDU 1003 MAX—SUM
Problem Description
Given a sequence a[1],a[2],a[3]……a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.

Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).

Output
For each test case, you should output two lines. The first line is “Case #:”, # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.

Sample Input
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5

Sample Output
Case 1:
14 1 4

Case 2:
7 1 6

之前写这题的时候找不到思路,然后才知道是动态规划,后来看别的程序,确定自己看懂后,也没有直接自己在动手写一遍,现在过了些日子在自卸看看去写,还是找不到写的思路。所以现在是又看一遍大佬们怎们写。

推荐这个博客(是老师的博客)恩很适合学习,并且里面的很多代码多会让自己有更多的思路。
这是老师写的代码HDU—1003

这是在又看了一遍这道题然后理解自己手敲了一遍基本和老师的一样。

#include<iostream>using namespace std;int main(){    int maxn, maxstart, maxend;    int now, sum,sumstart,n,m;    cin >> n;    for (int i = 1; i <=n;i++)    {        cin >> m;            cin >> now;            sum = maxn = now;            maxstart = maxend = sumstart = 1;            for (int j = 2; j <= m; j++)            {                cin >> now;                if (now > now + sum)                    sum = now, sumstart = j;                else                    sum += now;                if (sum > maxn)                    maxn = sum, maxstart = sumstart, maxend = j;            }            cout << "Case " << i << ":"<<endl;            cout << maxn << " " << maxstart << " " << maxend << endl;            if (i<n)                cout << endl;        }    return 0;}

我想说,别看它看似简单,在下还是想了很久,未果。后仔细观摩,还是懂的,只要将现在输入的存下计算最大值,在不在递增时候重新计算最大序列和存储的现有比较。写好dp的路很长。
继续ing

原创粉丝点击