题目链接:http://poj.org/problem?id=2184
博主也是新学dp的,不保证下面的内容的正确性,可能自己哪里理解错了,欢迎指正。
也是看了其它的解题报告,不过写得有点简略了,理解上花了点时间,下面相当于加深理解。
对于一个新学dp的人来说,这道题是噩梦。负数的处理,状态,状态转移,变量处理。当然,啃掉他,收获绝对很大,对dp会有新的认识。
先来说下题目大意吧,给出N头牛,每头牛都有智力值和幽默感,然后,这个题目最奇葩的地方是,它们居然可以是负数!!现在叫你求出其中的牛中,智力值总数和幽默感总数加起来最大的值,当然,智力值的总数必须大于等于零,幽默感总数也是。
一开始看到我直接跪了,尽管知道这题可以用dp解,但毫无思路,去找解题报告也是看不出个因为所以然。折磨了一两个钟,终于明白了点什么。
暂且不管负数,对于每头牛,我们有两种选择,要么选,要么选。看到这,就会觉得跟01背包很像,但是有 2 个变量来描述此状态的特征,智力,幽默感,并且他们可能是负数的。
如果此题选择dp来解,我们要想办法把它转换成01背包。
下面转换01背包的方法。
首先,下面的模板是 一维数组解背包问题 。
dp[i] = max(dp[i],dp[i-w[i]]+v[i])
首先,针对2个变量,智力,幽默感,我们定义i是前i头牛的智力总和,dp[i]存储的是此时智力总和为i时,幽默感总数的最大值。有人或许会问,题目叫我们求智力和幽默感的总数最大值啊,这dp最后得出的只是幽默感总数的最大值啊?没关系,求出整个dp后,将每个d[i] 和 i相加 看谁大就行了,别忘了,i就是智力总和。
这一步是锁定变量。
开始下一步前,我们先来定义一下dp数组的大小吧。
最多有100头牛,每个牛的智力范围在 -1000 – 1000 之间,
那他们的总和就是 落在 -1000*100 – 100*1000这个区间了里,也就是我们的d