本文主要是介绍技能树上的dp问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Description
热爱电子娱乐的同学们对于技能树一定不陌生.就是说,要先学习低级的垃圾技能,特定
的几个垃圾技能学会了,才能学习更强的技能.比如说,要先学火球术和烈火墙,才能学习地狱
烈焰.科技树也是一样.要先研究出电力和内燃机,才能研究工业学.那么,现在我们把问题简化,
这是一个技能树(或者科技树).格子上的数,是威力值.要先学会第一排第二个和第三个,才能
学会第二排的第二个.每个技能学习的前提都是左上和右上的两个技能.假设现在有一个第一
层有N 个技能的技能树,而且技能点是有限的,只能学习M 个技能,我们想知道最大的威力值
之和是多少.
(ps:这个不是样例)Input Format
第一行两个数N 和M,如题所述
之后N 行,第i 行,有n+1-i 个数.表示一个技能树.Output Format
输出一个数,表示最大威力值之和
Sample Input
4 5
1 1 1 1
1 2 1
1 1
1Sample Output
6
Data Limit
对于40%的数据,N<=10
对于100%的数据,N<=50,M<=500,所有数据都在int 之内.
技能树上的dp是一种不容易想到的dp问题,因为这种树状结构的dp大家都很熟悉,拿到这道题很容易就想成了树规或者从上向下,从下向上之类的dp问题,但是看到这道题的数据范围又是这么小,一看就有问题,然后就卡住了,最后只能写一个 O(2n) 的暴力。
那么现在我们仔细看看一下这道题,因为dp要无后效性(当前的状态只与前一个状态有关,而再前面的状态影响不了当前的状态,当前的状态也只能影响它后面的状态,不能影响再后面的状态),而如果我们从上向下dp的话,能不能去某一个数必须要看它上面的伞状结构的那一部分取没有,完全没法正常dp,方程一直列不出来。
我们就开始考虑,如何是我们的dp达到无后效性呢?
仔细观察我们可以发现无论我们怎么取,轮廓线都是一条锯齿状的折线。
我们发现每一列只有一个点在轮廓线上,而这些点,就是我们可以用来dp的点。
我们考虑从左向右dp,每一个在轮廓线上面的点只能有它前一列的上面或者下面得来,符合dp的无后效性
如上图,我们设“14”在第一行第一列,“33”在第二行第二列密码“15”在第一行第三列
而如果取一个点,也就说明要取它上面的所有点,我们可以先预处理将每个点上面点的数量存在num数组,价值和存在sum数组,f[k][i][j]表示[i][j]轮廓线取到这个坐标,一共取了k个数的最大值,然后开始状态转移!
这篇关于技能树上的dp问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!