初等动态规划刷题感想

几天做掉了洛谷上普及组的四个动态规划题组,刚开始完全是懵的,知道是动态规划但不知如何下手,只能看看题解依葫芦画瓢写,后续有了一系列的总结,稍微有些想法,到最后还是有些糊里糊涂地写完了。

在这里还是和往常一样,对动态规划问题的思考起点与后续思路做一下归纳,并对哪些题需要用动态规划做一下分析。

全是自己的感想,不一定正确

先附上一张图:
在这里插入图片描述

动态规划问题的特点

【1】问题的目标是求一个问题的最优解;//……最大值是多少;……最快是什么时间……;……最多能装多少;……

【2】整体问题的最优解依赖于各个子问题的最优解;//可以细分,即状态转移方程的作用

【3】把大问题分解成若干个小问题,这些小问题之间还有相互重叠的更小的子问题;//某一个点的状态可能会被运用多次

【4】从上往下分析问题,从下往上解决问题。//细分到极致后,从最初的初始值再推回算出后续结果

另外,动态规划问题中的每一个状态都具有下面的性质:如果给定某一阶段的状态,则在这一阶段以后过程的发展不受这阶段以前各段状态的影响,所有各阶段都确定时,整个过程也就确定了。换句话说,过程的每一次实现可以用一个状态序列表示,在前面的例子中每阶段的状态是该线路的始点,确定了这些点的序列,整个线路也就完全确定。从某一阶段以后的线路开始,当这段的始点给定时,不受以前线路(所通过的点)的影响。状态的这个性质意味着过程的历史只能通过当前的状态去影响它的未来的发展,这个性质称为无后效性,它也是动态规划问题可以自下而上解决问题的原因。
简而言之:在动态规划的状态转移方程,我们仅需知道前一阶段的结果,即可推出当前的值,至于前段的值是如果得到的,经过了哪些状态,我们并不需了解。

我们可以根据以上信息判断是否需要使用动态规划来解决问题。

动态规划问题的思考切入点

1.在确定使用动态规划来解决问题后,第一个难点就是状态转移方程的基础建立

动态规划问题中状态的保存与计算是依靠数组实现的,那么判断开几维数组是首先应解决的问题。对于每个问题,我们应先确定有多少个状态量,并确定其之间是否独立,如有联系,可将其合并,并根据最后剩余的状态量决定数组的维数。
例如洛谷P1156垃圾陷阱
在这里插入图片描述
我们可知状态量有时间、垃圾的个数、血量、高度。但仔细思考可知时间可由其余的几个状态量推导出,所以状态转移方程里不需要它,那么现在剩余三个状态,所以解题方法是开一二维数组,并在i、j(两状态量)变化时对数组里存的第三状态量进行更新,在此基础上对状态转移方程进行推导。

又如洛谷P1541乌龟棋
在这里插入图片描述
这是一道看似背包的问题,但由于要全用完,所以解决方法有不同。在此题中,我们的状态量有卡片的总数、四种卡片各有的数量、爬行所得分数。但卡片的总数可由四种卡片推出,剩余五个状态量,那么这题的状态转移方程中的数组要开四维,并在四种卡牌的使用数变化时对数组中储存的步数进行更新。

2.在维数确定时,对状态转移方程进行补全

先前多次提到状态转移,那么什么是状态转移?还是那上面两题举例,垃圾题里,吃是一种选择(状态),填是另一种选择(状态),所以在每次可以操作的时候,只有两种选择,可以以此推出状态转移方程,此外,对特殊情况(是否存在某一种转移方向不成立的情况),用if条件对此进行约束。
那么,P1156的状态转移方程为:

dp[i+1][j+infor[i+1].h]=max(dp[i+1][j+infor[i+1].h],dp[i][j]+infor[i].f-infor[i+1].f);//填 
dp[i+1][j]=max(dp[i+1][j],dp[i][j]+infor[i].f-infor[i+1].f+infor[i+1].t);//吃

并对死亡与离开状况进行特判即可。

在P1541里,状态转移方程为:

if(a!=0)    F[a][b][c][d]=max(F[a][b][c][d],F[a-1][b][c][d]+num[r]);//用卡1
if(b!=0)    F[a][b][c][d]=max(F[a][b][c][d],F[a][b-1][c][d]+num[r]);//用卡2
if(c!=0)    F[a][b][c][d]=max(F[a][b][c][d],F[a][b][c-1][d]+num[r]);//用卡3
if(d!=0)    F[a][b][c][d]=max(F[a][b][c][d],F[a][b][c][d-1]+num[r]);//用卡4

在前一段中,我们提到可以把大问题分解成若干个小问题,且整体问题的最优解依赖于各个子问题的最优解,这就是通过状态专题方程实现的。我的理解是:这里的小问题泛指此问题中的任意一种状态,即若我们要求某一值为m,另一值为n时的状态,这里的m、n既可以表示我们当前题目给的条件,也可以表示我们子问题的状态量,甚至可以表示此题的父问题的状态量。简而言之,对于任意的一个m、n值,我们都应能用同样的方法把他的结果算出来,即状态转移方程适用于所有情况,对于每一个点,我们都能用同样的式子求解。所以在建立状态转移方程时,我们要优先关注泛性,以此写出方程,再在此基础上对特殊态进行判断。

3.利用状态转移方程对值进行更新

状态转移方程写好后,就要依此对数组中的值进行更新,可是,如何更新,从左还是右,是由当前值更新后续点还是利用先前值更新此点,这些都是我们在每道题要遇到的抉择(应该只有四种情况吧)。我不知到如何总结,暂时也还没摸索出什么结论,当前的想法是,作为起点更新后续值时(向右?看情况而定吧),此点必须是状态已经确定的点(已经做过所有的更新可能,取的值已是最优解);作为终点由更新前序点更新时(向左?同上),前序点也必须是状态已经确定的点。不能随意覆盖,要事先考虑。

总结::
动态规划多刷题,要在做题中产生感觉????膜法 反正这只是普及组是暂时的感想,做完提高组的再写一次吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值