信息学奥赛NOIP动态规划入门
NOIP普及讲座3-动态规划1

• (1)划分阶段:按照问题的时间或空间特征,把 问题分为若干个阶段; • (2)确定状态和状态变量:将问题发展到各个阶 段时所处的各种情况用不同状态表示出来; • (3)确定决策并写出状态转移方程:一般是根据 相邻两个阶段各状态之间的关系来确定决策; • (4)寻找边界条件:给出的状态转移方程是一个 递推式,必须有一个递推的边界条件; • (5)编写程序。
从搜索到动态规划
引例(数塔问题)
• 设有一个三角形的数塔,顶点为根结点,每个结 点有一个整数值。从顶点出发,可以向左走或向 右走,从根结点13出发向左、向右的路径长度可 以是: 13 13-11-7-14-7,其和为52 11 8 13-11-12-14-13,其和为63 • 若要求从根结点开始, 26 7 12 请找出一条路径,使 8 15 6 14 路径之和最大,输出路 24 7 13 径的长度。 12
输入 第一行是一个整数N(不超过15),表示导弹数。 第二行包含N个整数,为导弹依次飞来的高度(雷达给出的高 度数据是不大于30000的正整数)。 输出 一个整数,表示最多能拦截的导弹数。 样例输入 8 389 207 155 300 299 170 158 65 样例输出 6
【问题分析】 状态: f[i]代表打下第i颗导弹最多能打多少颗导弹 方程: f[i]=max(f[j])+1(1<=j<i)且第i颗导弹的高度要高于 第j颗导弹的高度
11
• 【问题分析】 (1)贪心法
• 【问题分析】 (2)搜索:
• 【问题分析】 (3)动态规划:
Байду номын сангаас
13 11 12 7 14 7 15 8 26 8 24
6 12
13
11
CCF中学生计算机程序设计能力评级信息学奥赛NOIP动态规划算法及优化

动态规划算法 及优化
Codeforces 815C Karen and Supermarket
背包类问题 数据结构优化 决策单调性 计数
可以发现依赖关系形成了一棵树,因此可以考虑在树上
进行 DP。需要注意的是,本题中物品的价格可能非常大, 但是每个物品的收益只有 1,因此我们 DP 时第二维表示的 应当是买了多少个物品。
动态规划算法 及优化
背包类问题 数据结构优化 决策单调性 计数
动态规划算法及优化
动态规划算法 及优化
背包问题
背包类问题 数据结构优化 决策单调性 计数
01 背包:n 个物品,每个物品有价格 ci 及收益 wi ,问 m 元最多能得到多少收益。
完全背包:n 种物品,每种物品有价格 ci 及收益 wi,并 且每种物品能买无限个,问 m 元最多能得到多少收益。
n ≤ 500, m ≤ 4000, di ≤ 100。
动态规划算法 及优化
BZOJ4182 Shopping
背包类问题 数据结构优化 决策单调性 计数
先考虑我们知道必选某个节点时怎么做。可以把这个点
当成根,那么问题就转化为了一个树上依赖背包问题。 考虑用和上一题类似的方法进行 DP。令 fi,j 表示在节点
背包类问题 数据结构优化 决策单调性 计数
树上依赖背包其实还有一个经典的做法。考虑一边 dfs 一边 DP。dfs 到节点 i 的时候,我们先把 DP 数组拷贝一份, 表示不选 i 的子树时的背包。接着我们用多重背包的做法加 入商品 i,并且强制至少买一个商品 i。然后我们再依次 dfs 进每个儿子的子树中,回溯到 i 时我们就得到了在 i 的子树 中买了物品的背包,把它与原先拷贝的背包取个 max 即可。 这样复杂化即可。这样加入一个物品的复杂度是 O(m)
(完整版)信息竞赛复习资料5--动态规划(NOIP)

第一章什么叫动态规划1.1 多阶段决策过程的最优化问题1、问题的提出首先,例举一个典型的且很直观的多阶段决策问题:[例] 下图表示城市之间的交通路网,线段上的数字表示费用,单向通行由A-〉E。
求A—〉E的最省费用。
如图从A到E共分为4个阶段,即第一阶段从A到B,第二阶段从B到C,第三阶段从C到D,第四阶段从D到E。
除起点A和终点E外,其它各点既是上一阶段的终点又是下一阶段的起点。
例如从A到B的第一阶段中,A为起点,终点有B1,B2,B3三个,因而这时走的路线有三个选择,一是走到B1,一是走到B2,一是走到B3。
若选择B2的决策,B2就是第一阶段在我们决策之下的结果,它既是第一阶段路线的终点,又是第二阶段路线的始点.在第二阶段,再从B2点出发,对于B2点就有一个可供选择的终点集合(C1,C2,C3);若选择由B2走至C2为第二阶段的决策,则C2就是第二阶段的终点,同时又是第三阶段的始点。
同理递推下去,可看到各个阶段的决策不同,线路就不同。
很明显,当某阶段的起点给定时,它直接影响着后面各阶段的行进路线和整个路线的长短,而后面各阶段的路线的发展不受这点以前各阶段的影响。
故此问题的要求是:在各个阶段选取一个恰当的决策,使由这些决策组成的一个决策序列所决定的一条路线,其总路程最短。
具体情况如下:(1)由目标状态E向前推,可以分成四个阶段,即四个子问题。
如上图所示。
(2)策略:每个阶段到E的最省费用为本阶段的决策路径。
(3)D1,D2是第一次输人的结点。
他们到E都只有一种费用,在D1框上面标5,D2框上面标2。
目前无法定下,那一个点将在全程最优策略的路径上。
第二阶段计算中,5,2都应分别参加计算.(4)C1,C2,C3是第二次输入结点,他们到D1,D2各有两种费用.此时应计算C1,C2,C3分别到E的最少费用. C1的决策路径是 min{(C1D1),(C1D2)}.计算结果是C1+D1+E,在C1框上面标为8。
最新信息学奥赛NOIP动态规划入门教学文案

阶段4
阶段4:F(D1)=3;F(D2)=4;F(D3)=3 阶段3:F(C1)=min{F(D1)+C1到D1的路径长度,
F(D2)+C1到D2的路径长度} F(C2)……
阶段1
阶段2
阶段3
阶段4
我们把F(x) 称为当前x的状态;
在这个例子中每个阶段的选择依赖当前的状态,又 随即引起状态的转移,一个决策序列(E –D3-C4B2-A)就是在变化的状态中产生的,故有“动态”的 含义。
方各有个数,从第一行的数开始,每次可以选择
向左下或是向右下走一格,一直走到最下行,把
沿途经过的数全部加起来。如何走才能使得这个
和尽量大?。
穷举?贪心?搜索?
数字三角形
数组存储
格子编号
深搜(递归实现)
程序清单: void f( int i, int j )
{ s=s+a[ i ][ j ]; if ( i==4 ) if ( s > max ) max = s; else { f( i+1, j ); s=s-a[ i+1] [ j ]; f( i+1, j+1); s=s-a[ i+1] [ j+1]; }
if( i == n ) return a[i][ j];
if(d[ i ][ j ] >= 0) return d[i][ j];
d[i][ j] = a[i][ j]+max(solve ( i+1, j ), solve ( i+1 , j +1) );
这样做是正确的, 可惜时间效率太低 。低效的原因在于
重复计算。
重复计算
dt(1,1) 的调用关系树
《noip动态规划讲解》PPT课件

他 们 的 身 高 分 别 为 T1,T2,…,TK, 则 他 们 的 身 高 满 足 T1<...<Ti>Ti+1>…>TK(1<=i<=K)。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可 以使得剩下的同学排成合唱队形。 【输入文件】
精选PPT
5
设有由n个不相同的整数组成的数列,记为: a(1)、a(2)、……、a(n)且a(i)<>a(j) (i,j<=n) 例如3,18,7,14,10,12,23,41,16,24。 若存在i1<i2<i3< … < ie 且有a(i1)<a(i2)< … <a(ie)则称为长度为e的不下降序列。如上例中3, 18,23,24就是一个长度为4的不下降序列,同时 也有3,7,10,12,16,24长度为6的不下降序列。 最长的不下降序列就是求长度最长的子序列。
If f[j]<f[j-a[i]]+b[i] Then f[j]:=f[j-a[i]]+b[i];
精选PPT
15
Sample Problem4
金明的预算方案(NOIp2006)
【问题描述】 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己
专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购 买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”。今天一早,金明 就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个 主件的。如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件 可以有0个、1个或2个附件。附件不再有从属于自己的附件。金明想买的东西很 多,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一个重要度,分为 5等:用整数1~5表示,第5等最重要。他还从因特网上查到了每件物品的价格 (都是10元的整数倍)。他希望在不超过N元(可以等于N元)的前提下,使每 件物品的价格与重要度的乘积的总和最大。
信息学奥赛——动态规划实例分析及程序实现

全国青少年信息学奥林匹克联赛动态规划实例分析及程序实现一、数字三角形(图3.1-1)示出了一个数字三角形。
请编一个程序计算从顶至底的某处的一条路径,使该路径所经过的数字的总和最大。
●每一步可沿左斜线向下或右斜线向下走;●1<三角形行数≤100;●三角形中的数字为整数0,1,…99;输入数据:由INPUT.TXT文件中首先读到的是三角形的行数。
在例子中INPUT.TXT表示如下:573 88 1 02 7 4 44 5 2 6 5输出数据:把最大总和(整数)写入OUTPUT.TXT文件。
上例为:30738810274445265(图3.1-1)二、算法分析只要对该题稍加分析,就可以得出一个结论:如果得到一条由顶至底的某处的一条最佳路径,那么对于该路径上的每一个中间点来说,由顶至该中间点的路径所经过的数字和也为最大。
因此该题是一个典型的多阶段决策最优化的问题。
我们采用动态规划中的顺推解法。
按三角形的行划分阶段。
若行数为n, 则可把问题看作一个n-1个阶段的决策问题。
从始点出发,依顺向求出第一阶段、第二阶段,……,第n-1阶段中各决策点至始点的最佳路径,最终求出始点到终点的最佳路径。
设:fk(Uk)━━从第k阶段中的点Uk至三角形顶点有一条最佳路径,该路径所经过的数字的总和最大,fk(Uk)表示为这个数字和;由于每一次决策有两个选择,或沿左斜线向下,或沿右斜线向下,因此设Uk1━━k-1阶段中某点Uk沿左斜线向下的点;Uk2━━k-1阶段中某点Uk沿右斜线向下的点;dk(Uk1)━━k阶段中Uk1的数字;dk(Uk2)━━k阶段中Uk2的数字;因而可写出顺推关系式fk(Uk)=max{fk-1(Uk)+dk(Uk1),fk-1(Uk)+dk(Uk2)}f0(U0)=0;K=1,2,3,4,……n经过一次顺推,便可分别求出由顶至底N个数的N条路径,在这N条路径所经过的N个数字和中,最大值即为正确答案。
三、程序分析根据上述顺推关系,我们编写程序如下:Program ID1P1;ConstMaxn = 100;TypeNode = RecordVal, Tot : Integer{ 当前格数字; 从[1,1]到当前格的路径所经过的数字和} End;VarList : Array [1..Maxn, 1..Maxn] of Node; { 计算表} N, Max, { 行数, 最大总和}I, J : Integer; { 辅助变量}Fi : Text; { 文件变量}Procedure Init;BeginAssign(Fi, 'INPUT.TXT'); { 文件名和文件变量连接} Reset(Fi); { 文件读准备}Readln(Fi, N); { 读三角形行数}For i := 1 to N Do { 读入三角形各格的数字}For j := 1 to i DoRead(Fi, List[i, j].Val);Close(Fi)End;{init}Procedure Main;BeginList[1, 1].Tot := List[1, 1].Val; { 从[1,1]位置开始往下顺推}For i := 2 to N DoFor j := 1 to i Do BeginList[i, j].Tot := -1; { 从[1,1]至[i,j]的数字和初始化}If (j <> 1) And(List[i - 1, j - 1].Tot + List[i, j].Val > List[i, j].Tot) ThenList[i, j].Tot := List[i - 1, j - 1].Tot + List[i, j].Val;{ 若从[i-1,j-1]选择右斜线向下会使[1,1]至[i,j]的数字和最大,则决策该步} If (j <> i) And(List[i - 1, j].Tot + List[i, j].Val > List[i, j].Tot) ThenList[i, j].Tot := List[i - 1, j].Tot + List[i, j].Val{ 若从[i-1,j]选择左斜线向下会使[1,1]至[i,j]的数字和最大,则决策该步} End; {for}Max := 1;{ [1,1]至底行各点的N条路径所经过的数字和中,选择最大的一个输出} For i := 2 to N DoIf List[N, i].Tot > List[N, Max].Tot ThenMax := i;Writeln(List[N, Max].Tot) { 输出最大总和}End; {main}BeginInit; { 读入数字三角形}Main { 求最大总和}End.{main}二、Problem : 打鼹鼠Contents: 有个n*n个格子,在m个时间点上的不定格子里有数量不等的鼹鼠出现,机器人每次只能向前后左右移动一个格子,问最多机器人能打多少鼹鼠?(n<=1000, m<=10000)Type: 动态规划Difficulty: 2Source: HNOI2004_day_*_*Solution :a)记得学OI不到几个月,高一刚上来就做的这道题..着实郁闷了半天,有一个思路是开1000*1000 的数组乱搞…忘了可以过几个来着..b)又翻到这道题的时候是2月份了..发现f[i]表示:如果机器人最后打死的老鼠是第i只,这种情况下机器人最多可以打死多少老鼠。
全国信息学奥赛NOI培训教程(最新整理)

全国信息学奥赛NOI培训教程(最新整理)使用”视图"—--—"文档结构图"可大大方便阅读本文档目录计算机基础知识-———--—-—--——---———-———---—-——6 第一章计算机基础常识第二章操作系统简介第三章计算机网络第四章计算机信息安全基础知识Pascal 语言-——————————--—-————---——-———-——-——-19Pascal语言概述与预备知识第一章开始编写pascal语言程序第二章Pascal语言基础知识第三章顺序结构程序设计第四章选择结构程序设计第五章循环结构程序设计第六章数组与字符串第七章函数和过程第八章子界与枚举类型第九章集合类型第十章记录与文件类型第十一章指针第十二章程序调试常用算法与策略———-——--———-—--—-———-————————--——--56第一章算法的概念第二章递归第三章回溯第四章排序第五章查找第六章穷举策略第七章贪心算法第八章分治策略数据结构-————-—-——-——--——--————---———-—————101第一章什么是数据结构第二章线性表第三章栈第四章队第五章树第六章图动态规划-——————---———----———-—-—-—---—-—-——144第一章什么叫动态规划第二章用动态规划解题第三章典型例题与习题第四章动态规划的递归函数法第五章动态规划分类1数学知识及相关算法第一章有关数论的算法第二章高精度计算第三章排列与组合第四章计算几何第五章其它数学知识及算法图论算法-————---—--—---—————-—-——-—-—-—————192第一章最小生成树第二章最短路径第三章拓扑排序(AOV网)第四章关键路径(AOE网)第五章网络流第六章图匹配搜索算法与优化——-———————————--——-—-—---—-—--—-—-—218第一章双向广度优先搜索第二章分支定界法第三章A*算法青少年信息学奥林匹克竞赛情况简介信息学奥林匹克竞赛是一项旨在推动计算机普及的学科竞赛活动,重在培养学生能力,使得有潜质有才华的学生在竞赛活动中锻炼和发展。
信息学奥赛简介NOIP及C++基础知识第一讲

6. p=(a+b+c)/2;
思考:语句5和6可以交换吗?
7. s=sqrt(p*(p-a)*(p-b)*(p-c));
8. printf("%0.3lf\n",s);
9. return 0;
10.}
1. #include<cstdio> 2. #include<cmath> 3. int main(){
渡河的方法与步骤: 第一步:农夫带 过河 第二步:农夫划船回来 第三步:农夫带 过河 ……
猜数字(1..1000)
• 回答大了或小了
猜 生 日?
月? 日?
二分法
每次舍弃“一半”不符合条件的情况,逐渐缩小范围, 最后找到问题的解
枚举算法
基本思想: 按照问题本身的性质,一一列举出该问题所有可
能的解,并根据问题的条件对各解进行逐个检验,从 中挑选出符合条件的解,舍弃不符合条件的解。
开,最后用分号结束。
知识点1:格式化输入函数scanf
格式: scanf("格式化字符串",地址列表);
说明: 1)地址列表中给出各变量的地址(即变量名的前面加“&”
符号)。 2)格式控制符由%和格式符组成,作用是将要输入的字符
按指定的格式输入,如%d,%lf等 3)格式字符和和变量的类型一一对应:类型和个数一致。
{
double r,s;
//定义实型变量
scanf("%lf",&r);
//输入r的值,&符号不能漏掉
s=PI*r*r;
//计算圆的面积
printf("%.2lf\n",s); //显示计算结果,结果保留2位小数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
最大连续子序列和(Maximum Continuous Subsequence Sum)
转移方程: dp[i]= max { A[i] , dp[i-1] + A[i] } 边界:dp[0]=A[0] 代码: dp[0] = A[0]; for (int i=1 ; i < n ; i++){ dp[i]= max ( A[i] , dp[i-1] + A[i] ) }
阶段4:F(D1)=3;F(D2)=4;F(D3)=3 阶段3:F(C1)=min{F(D1)+C1到D1的路径长度, F(D2)+C1到D2的路径长度} F(C2)……
阶段1 阶段2 阶段3
阶段4
我们把F(x) 称为当前x的状态; 在这个例子中每个阶段的选择依赖当前的状态,又 随即引起状态的转移,一个决策序列(E –D3-C4B2-A)就是在变化的状态中产生的,故有“动态”的 含义。
如何选呢?
其中较大的一个,再加上a(i,j)的值就是d[i,j]。
d[i,j]=a[i,j]+max{d[i+1,j],d[i+1,j+1]}
思考:边界条件?
思想:从上向下思考,从底向上计算
24 16
8
13
23
21
数字三角形
方法1:递推计算
void solve () { int i , j; for( j = 1; j <= n; j ++) d[n][j ] = a[n][j]; for(i = n -1; i >= 1; i - -) for( j = 1; j <= i; j ++) d[i][j ] = a[i][j ] + max (d[i +1][ j], d[i +1][ j +1]); }
格子编号
分析:考察 设以格子(i,j)为首的“子三角形”的最大和为d[i,j] (我们将不加区别的把这个子问题(subproblem) 本 身也称为d[i,j]),则原问题的解是d[1,1]我们关心 的是从某处出发到底部的最大和: 从(2,1)点出发的最大和记做d[2,1]; 从(2,2)点出发的最大和记做d[2,2]; 从(1,1)出发有两种选择(2,1)或(2,2) 在已知d[2,1]和d[2,2]的情况下,应选择较大的一个。
方法2:递归计算
dt(1,1) 的调用关系树
方法3:记忆化搜索
这个方法和直接递归非常类似,但加入了记忆 化(memoization) ,保证每个结点只访问一次。
// initially , all d[i][j] are -1
int solve ( int i , int j)
{ if( i == n ) return a[i][j]; if(d[ i ][ j ] >= 0) return d[i][j]; d[i][j] = a[i][j]+max(solve ( i+1, j ), solve ( i+1 , j +1) ); return d[i][j]; } 时间复杂度O(n2) 不必事先确定各状态的计算顺序
问题转换为dp[0],dp[1],…,dp[n-1]中的最大 者。
最大连续子序列和(Maximum Continuous Subsequence Sum)
dp[i]表示以A[i]作为末尾的连续序列的最大和( A[i]必须作为序列的末尾); 只有两重情况: 1、这个最大和的连续序列只有一个元素,即以A[i] 开始,以A[i]结尾;最大和就是A[i]本身。 2、这个最大和的连续序列有多个元素,从前面某处 A[p]开始(p<i);一直到A[i]结尾。 也就是 dp[i-1]+A[i]; A[p]+…+A[i-1]+A[i]=dp[i-1]+A[i];
程序清单: void f( int i, int j ) { s=s+a[ i ][ j ]; if ( i==4 ) if ( s > max ) max = s; else { f( i+1, j ); s=s-a[ i+1] [ j ]; f( i+1, j+1); s=s-a[ i+1] [ j+1]; } }
需要考虑两个部分:一是递推的顺序,二是递归边界(也是递推 起点)。
•从直接递归和后两种方法的比较可以看出:重叠子问题
(overlapping subprob-lems) 是动态规划展示威力的关键。
考察:d(1,1);d(2,1);d(2,2)……这些问题 的共性:都是求从一个位置出发到底部的最大 值;是一个共同的问题。
思考:考虑更一般的情况,当前位置(i,j)看 成一个状态, 定义状态(i,j)的指标函数d(i,j) 为从 格子(i,j)出发时能得到的最大和(包含格 子(i,j)本身的值)。 原题的解:?d(?,?)
d[1,1]
格子编号
思考:观察不同状态如何转移的。 从格子(i,j)出发有两种决策。 如果(i,j)格子里的值为a (i ,j) 向左走需要求“从(i+1,j)出发的最大和”, 就是d[i+1,j]。 向右走需要求“从(i+1,j+1)出发的最 大和”,就是d[i+1,j+1]。
时间复杂度O(n2) 在计算d[i][j]前,d[i+1][j],d[i+1][j+1]已计算好了!
int solve ( int i , int j) { if (i == n) return a[i][j]; else return a[i][j] + max( solve (i+1,j), solve (i+1 , j +1)); }这样做是正确的, 可惜时间效率太低。 低效的原因在于重 复计算。 重复计算
最短路径问题---求A到E的最短路的长度
穷举?贪心?搜索?
阶段1 阶段2 阶段3
阶段4
思考: 仔细观察本图路径的特殊性,可以分成4个阶段: 第一阶段:A经过A-B1或A-B2到B 第二阶段:B1有三条路通……;B2有两条通路……
阶段1
阶段2
阶段3
阶段4
思考:倒着推;设F(x)表示x到E的最短路径的长度
样例输入: 8 389 207 155 300 299 170 158 65 样例输出: 6(最多能拦截的导弹数)
题目分析: 给定一个正整数序列,求出其中最长下降序列:例如: 389 207 155 300 299 170 158 65 389 300 299 170 158 65 所求的问题:从某一个位置开始的最长下降序列 寻找一个状态?
d(2,1) d(2,2)
重叠子问题
考察:d(1,1);d(2,1);d(2,2);可以发现 每个子问题结果都是最优的。
d(2,Байду номын сангаас)
d(2,2)
最优子结构
什么是动态规划?
动态规划是求解包含重叠子问题的最优化方法 动态规划的性质? 子问题重叠性质:在用递归算法自顶向下对问题进行
求解是,每次产生的子问题并不总是新问题,有些子问题 可能被重复计算多次。动态规划算法利用此性质,对每个 子问题只计算一次,然后将其结果保存起来以便高效重用。 最优化子结构性质:若问题的最优解所包含的子问题 的解也是最优的,则称该问题具有最优子结构性质(即满 足最优化原理)。 能用动态规划解决的求最优解问题,必须满足最优解 的每个局部也都是最优的
{ 第1列} {对角线}
思考:最后的结果:?? max{d[n][1],d[n][2]……d[n][n]}
这种方法本 质就是递推
例3:最大连续子序列和(Maximum Continuous Subsequence Sum)
给定k个整数的序列{A1,A2,...,Ak },其任意连续 子序列可表示为{ Ai, Ai+1, ...,Aj },其中 1 <= i <= j <= k。最大连续子序列是所有连续子序 中元素和最大的一个。 例如给定序列{ -2, 11, -4, 13, -5, -2 },其 最大连续子序列为{11,-4,13},最大连续子序列 和即为20。 暴力枚举?时间复杂度为?能优化吗?复杂度?
向上考虑,观察不同状态如何转 移的。从格子(i,j)出发有两 种决策。
d(i,j)为:取d(i-1,j) 和d(i-1,j-1)中较 大的一个加上a(i,j)的和。
思考:边界情况:??
d[1][1]=a[1][1] d[i][1]=d[i-1][1]+a[i][1] d[i][i]=d[i-1][i-1]+a[i][i]
例2: 数字三角形 一个由非负数组成的三角形,第一行只有 一个数,除了最下行之外每个数的左下方和右下 方各有个数,从第一行的数开始,每次可以选择 向左下或是向右下走一格,一直走到最下行,把 沿途经过的数全部加起来。如何走才能使得这个 和尽量大?。 穷举?贪心?搜索?
数字三角形
数组存储
格子编号
深搜(递归实现)
1.动态规划比穷举具有较少的计算次数 从数塔问题可以看出,层数为k时, 穷举算法求路径的条数2k-1 动态规划计算的次数为: k (k 1) 2
穷举最多计算到n=20,动态规划可以算到n=100 2.递归需要很大的栈空间,而动规的递推法不需要栈 空间;使用记忆化搜索比较容易书写程序。
思考: 还有一种思考方法,从下
动态规划初步
引入:走楼梯
已知一个楼梯有n级,从下往上走,一步可以走一级 ,也可以走两级,走到第N级楼梯有多少种走法? 【输入格式】 一行一个整数n。 【输出格式】 一行仅有一整数,表示走到第n级有多少种走法。 【输入样例】 【输出样例】 2 2 【数据规模】 对100%的数据满足:0 < n ≤ 30。