题意
给你一个序列n个数组成,然后让你在里面找到m个子序列,让这m个子序列的和最大。
题解
$dp[i][j]$表示的是第j个数字在第i个子序列时的当前最优值。
$dp[i][j] = maxx(dp[i][j-1] + num[j] ,maxx(dp[i-1][k]) + num[j])$,k是从1到 $j-1$.
可以这么理解这个转移方程,对于当前的这个数字,如果把他放到第i个子序列中有两种情况,一个是他作为第i个子序列的第一个数字,另一个就是不作为第一个数字,作为第一个数字的时候是 $max(dp[i-2][k] + num[j]) ,1<=k<i $的意思是从之前的所有中找到 $i-1$ 个子序列的最大值+当前的值,不做为第一个的时候那么他前面的那个数字一定是i序列的,同一个子序列,又不是作为第一个,那么前面的那个货就一定是同一个子序列的,那么当前的值是$dp[i][j-1] + num[j]$,在两种决策中选择一个最有的就行了,还有就是$max(dp[i-1][k]+num[j])$的这个地方可以开一个数组记录下来,不能每次都跑,跑不起,再有就是这个题目没有给m的范围,所以开不了二维数组(目测不是很大,大的话会超时,但是肯定是先超内存在超时,所以为了保险,还是吧$dp[][]$压缩成一维的)那么状态转移就边成这样了$dp[j]$表示的是 j这个人在当前的这个子序列中的最优值,mk[j]表示的是在上一个子序列中1—j的dp的最大值,所以就变成 $dp[j] = maxx(dp[j-1] + num[j] ,mk[j-1]+num[j])$;还是 max(作为i个子序列的第一个元素,不是第一个元素取一个最大值)。在解释下代码的核心部分。
代码
1 |
|