The merchants were the most typical, each of them only sold exactly one item, the price was Pi, but they would refuse to make a trade with you if your money were less than Qi, and iSea evaluated every item a value Vi.
If he had M units of money, what’s the maximum value iSea could get?
Each test case begin with two integers N, M (1 ≤ N ≤ 500, 1 ≤ M ≤ 5000), indicating the items’ number and the initial money.
Then N lines follow, each line contains three numbers Pi, Qi and Vi (1 ≤ Pi ≤ Qi ≤ 100, 1 ≤ Vi ≤ 1000), their meaning is in the description.
The input terminates by end of file marker.
2 10 10 15 10 5 10 5 3 10 5 10 5 3 5 6 2 7 3
5 11
本来正常做的,状态转移方程为 dp[j] = max(dp[j], dp[j -price[i]] + value[i]);
可是结果与测试数据对不上。。就反复找啊,原因在哪。后来发现原来我的数组推导过程不对。假如说第二组测试数据。
5 10 5 的时候。我的背包容量为10,所以数组元素只有dp[10] = 5,可是当i++之后,下一个测试数据为 3 5 6。根据状态转移方程
dp[10] = max ( dp[10], dp[10 - 3] + 6 ) = 6. 可是买完第一个明明还能买第二个啊。但是如果先是买第二个再买第一个就数值正常。
就反复思考原因,没有办法。。。看了一眼提示,说按q-p排序就好。于是就反复想,为什么啊。。。没办法,又得看题解。。
杭电大神解释: 我们要保证的是,最先进行dp的结点必须是能开启dp[i]中i的最小值的结点。因为只有这样才能保证DP的后效性。我们必须保证dp[j-price[i]]可以被赋值,它就要被先赋值
查了一下动态规划的特性:
最优子结构:无论之前状态决策如何,局部最优解是构成全局最优解的必要条件
重叠子问题:。。。。
无后效性:动态规划法的最优解通常是由一系列最优决策组成的决策序列,最优子结构就是这些最优决策序列中的一个子序列,对于每个子序列再做最优决策会产生新的最优决策(子)序列,如果某个决策只受当前最优决策子序列的影响,而不受当前决策可能产生的新的最优决策子序列的影响,则可以理解这个最优决策具有无后效性。
刚开始看完全背包,完全背包应该也满足无后效性条件,因为它虽然可能多次选择前面的,但是它不改变前面的结果,只是改变当前决策的结果
自己理解:如果正常做就不满足无后效性的特性,假如按照第二组数据来看。就像上面说的,买完第一个还能买第二个,但是按照dp却不对,需要改变前一行的值才能使dp数组正确,这就是数组第一行决策受到了第二行决策影响,有后效性。所以要消除后效性。
按照大神的意思,应该是dp的正确性是因为它后面的依赖前面的也是正确的,
根据状态转移公式 dp[j] = max ( dp[j], dp[j - price[i]] + value[i]);
要保证dp后面正确,应该使dp[j - price[i]]不可能再被改变,dp[j-price[i]]式子中,j的值最小为want[i](商人只有你兜里的钱大于等于want[i]才卖给你东西)
所以,j -price[i] 的最小值为 want[i] - price[i].要保证 dp[j - price[i]]已经被赋值,就是保证前一行的want[i] - price[i]如果能被赋值一定要被赋值。
所以排序的顺序应该按照 want[i] - price[i]顺序排序才可以。
也就是按照q-p排序。
本题消除后效性方法:数组中下标小的数要先被赋值。以便后面访问此值是正确的