征途堆积出友情的永恒「堆优化dp」
直接写题解:
很简单的dp暴力转移式子:f[i]=MAX{f[j]+max(tax[j],sum[i]-sum[j])}
观察式子,只有一个变量sum[i];
而其他都为定量;
则考虑维护 两个定量:f[j]+tax[j] || f[j]-sum[j]
而要找耗费最小;考虑用堆维护一个量;
注意是一个量;
为什么不是两个量?
想想,你在dp式子中取的max;不是取tax[j]就是取deta(sum);
那就是说如果你使一个量主动;那么另一个量就是被动的,、由你确定的这个量决定的
所以就维护tax[j]+f[j];
按大小排序;然后取最优值;
设 pay=q.top.w; (tax[j]+f[j])
若pay>=f[j]-sum[j]+sum[i];那就用它呗,反正是合法的;
若pay<f[j]-sum[j]+sum[i] 那这种方案就不合法;那就把他的被动决策塞入另一个堆中维护;
那么会形成两个堆,两个堆中的状态都是合法的,然后直接取堆顶元素就是最优的;
而可能你会想到那第一个堆中的元素pop掉了,会不会有后效性;
其实不会;因为sum[i]-sum[j] 的sum[j]固定而sum[i]递增;
所以当他从1pop出去后,他在2中就会一直呆着了;
总结:
1.对于这种dp优化,若dp式子中出现变量很少而定量很多,就要考虑到维护定量;
2.而对于dp式子中有max(),min()之类的,说明主动决策决定被动决策;所以考虑维护两个决策中较容易维护的一方;然后让另一方成为被动;若遇到维护的值不再偏向于己方;
那就把这种状态pop掉,转换成另一方;让这种状态继续合法;对答案做贡献;
3.注意2中max的决策单调性;例如这个题中max有单调性,就可以无后效性的转化;
代码应该自己实现!