动态规划初学

数字三角形:

定义状态(i,j):表示当前所处位置

定义指标函数 d(i,j) :表示从格子(i,j)出发能得到的最大和

找到状态转移方程: d(i,j)=a(i,j)+max{d(i+1,j),d(i+1,j+1)}

总状态为O(n^2),每个状态决策为O(1),总的时间复杂度为O(n^2)。

方法:直接递归

缺点:重复计算过多

优化:记忆化搜索

或者: 递推计算(关键 边界和计算顺序)

DAG

嵌套三角形:

定义状态(i,j):表示矩形的二元关系,为了通过图来建模?

PS:(i)表示从结点i出发遍历能到达的结点

定义指标函数d(i):表示从结点i出发的最长路长度

找到状态转移方程:d(i)=max{ d(j)+1 | (i,j)属于E}

PS:矩形之间关系通过图建模表示出来,定义状态为从i点出发的最长路径,这是一个最优子结构。通过状态转移方程找出全局最优与局部最优的关系。

总状态为O(n),每个决策有O(n),时间复杂度为O(n^2)。

注意:因为起始点不定,有n种可能。

硬币问题:

定义状态(i):表示S减去v[n]之后还剩的硬币数额

定义指标函数d(i):表示剩余硬币额为i时最大最小硬币数

找到状态转移方程:d(i)=max{ d(S-v[i])+1, d(i) }

d(i)=min{ d(S-v[i])+1, d(i) }

总状态为O(S),每个状态的决策为O(n),时间复杂度为O(Sn)。

城市里的间谍(uva1025)

定义状态(i,j):表示所处时刻和所在车站号

定义指标函数d(i,j):表示等待的最短时间

找到状态转移方程:d(i,j)=min{ d(i,j), d(i+time[j],j+1) }当有向右开的车时

d(i,j)=min{ d(i,j), d(i+1,j)+1}没车等一分钟

d(i,j)=min{ d(i,j), d(i+time[j-1],j-1) }当有向左开的车时

状态有:O(nT),每个状态至多有3个决策,因此总的时间复杂度为O(nT)。

巴比伦塔(uva437)

定义状态(idx,k):表示所选立方体的编号和高度编号(因为用长宽作为数组可能太大且浪费空间太多)

定义指标函数d(idx,k):表示所选立方体总高度最大

找到状态转移方程:d(idx,k) =max{ d(idj)+blocks[idx][k] | (idx,k,idj,h)属于E}

状态总数为O(n),每个状态决策有O(n)个,时间复杂度为O(n^2)。

注意:因为起点不定,建立图表。如嵌套三角形。

旅行(uva1347)  与数字三角形相似

定义状态(i,j):表示两个人所处位置编号

定义指标函数d(i,j):表示走过1,2,...max(i,j)所有点,剩下的距离

找到状态转移方程:d(i,j)=min{ d(i+1,j),d(i+1,i) }

边界:d(n-1, j) = dist(n-1, n) + dist(j, n) (1 ≤ j < n-1)

最终所求答案就是dist(1, 2) + d(1, 2)

状态有:O(n^2),每个状态决策为O(1),总时间复杂度为O(n^2)。

时间: 2024-08-04 05:55:03

动态规划初学的相关文章

01背包和动态规划

做了一段时间NOI,做到动态规划看了几天算法书籍.还是没有深入,学了基本的动态规划,稍有一点体会,记录到这里. 背包是这样一类问题:在限定总质量前提下,从若干质量\价格对中,取哪些能使得价格最大. 动态规划是一种思想,简单的说,动态规划思想就是充分利用对子问题的计算结果来递推父问题结果.所以,动态规划具有较高的效率,省去了一些不必要的计算.这里主要关心表和递推关系,其实这两者是同一个东西,根据记录表来推得父问题的解,找到递推关系要依赖表记录子问题的解.不同的问题有不同的构建方式,所以我个人觉得,

动态规划专题 01背包问题详解 HDU 2546 饭卡

我以此题为例,详细分析01背包问题,希望该题能够为初学者对01背包问题的理解有所帮助,有什么问题可以向我提供,一同进步^_^ 饭卡 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14246    Accepted Submission(s): 4952 Problem Description 电子科大本部食堂的饭卡有一种很诡异的设计,即

DP(动态规划)学习心得

动态规划学习心得 说实话吧,动态规划(DP)确实是一个比较难的知识点,对于初学者来说,是一个难过的坎(笔者的脸呢?开玩笑.).动态规划就是我从初学开始遇到的最神奇的解法,它不同于暴力搜索,也不同于一般的贪心,能够以出乎人意料的时间复杂度(近似于O(n^2))解决一些难题,算法远远优于一般的深搜(O(2^n)).不过,动态规划的思维性比较强,必须会设好状态,正确写出状态转移方程,并且能够准确判断有无最优子结构. 其实有点像贪心,但是它有局部最优解推导向整体最优解的过程,形象一点说,动态规划的“眼光

清晰明了的javascript版动态规划

算法是一种艺术,给人感觉很不好接近,但是一旦你和ta熟络了,你就能发现这门艺术的内在是多么美妙且多变. 对于前端来说,算法也许不是最重要的,在日常工作中,几乎很少用到.所以很多人也不是很感冒. 不过呢,有句话这么说的:面试造火箭,上班拧螺丝.咱们得先学习造火箭,才能有拧螺丝的机会. 莫得办法,既然想要拧螺丝,就要有好活的老学到老的觉悟.否则连改锥都没了. 那么,看题. 给你一个表格,像这样的: 从 (0, 0) 到 (M, N)移动,并假设,每次只能向下或者向右移动一步,那么,请问一共有多少种不

快速上手leetcode动态规划题

快速上手leetcode动态规划题 我现在是初学的状态,在此来记录我的刷题过程,便于以后复习巩固. 我leetcode从动态规划开始刷,语言用的java. 一.了解动态规划 我上网查了一下动态规划,了解到动态规划是“带有备忘录的递归”, 而大多数用来理解动态规划的例子都是斐波那契数列,就是那个经典的递归式 f(i)=f(i-1)+f(i-2) ,f(1)=f(2)=1 那么我们就可以得到很多式子,比如求f(5): f(5)=f(4)+f(3); f(4)=f(3)+f(2); f(3)=f(2)

Leetcode 494 Target Sum 动态规划 背包+滚动数据

这是一道水题,作为没有货的水货楼主如是说. 题意:已知一个数组nums {a1,a2,a3,.....,an}(其中0<ai <=1000(1<=k<=n, n<=20))和一个数S c1a1c2a2c3a3......cnan = S, 其中ci(1<=i<=n)可以在加号和减号之中任选. 求有多少种{c1,c2,c3,...,cn}的排列能使上述等式成立. 例如: 输入:nums is [1, 1, 1, 1, 1], S is 3. 输出 : 5符合要求5种

活动选择的贪心算法与动态规划(未完成)

// greedy_algorithm.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include<queue> using namespace std; #define NofActivity 11 int c[NofActivity + 1][NofActivity + 1]; int reme[NofActivity + 1][NofActivity + 1]; //活动的

求不相邻金币相加和的最大值--动态规划1

求不相邻金币相加和的最大值. 输入n个金币的金币面值(正数自定义),求这些金币不相邻和的最大值. 动态规划问题1 设f(n)为第n个金币数的最大值,f(0)=0,f(1)=a[1],输入的数组从下标为1开始. f(n)=max{a[n]+f(n-2),f(n-1)}. 代码如下: import java.util.Scanner; public class Jin_bi_zui_da_zhi { public static void main(String[] args) { Scanner s

[动态规划] 黑客的攻击 Hacker&#39;s CrackDown Uva 11825

抽象为数学模型就是,  取尽可能多的互不相交的子集 ,  使得每一个子集都能覆盖全集 #include <algorithm> #include <cstring> #include <cstdio> using namespace std; int n; int P[1000],cover[1000],f[1000]; int main(){ scanf("%d", &n); for (int i = 0; i < n;i++) {