zoukankan      html  css  js  c++  java
  • 征途堆积出友情的永恒「堆优化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有单调性,就可以无后效性的转化;

    代码应该自己实现!

  • 相关阅读:
    C# 运用StreamReader类和StreamWriter类实现文件的读写操作
    C# 理解FileInfo类的Open()方法
    C# 运用FileInfo类创建、删除文件
    C# 创建子目录
    C# 目录下的文件操作
    C# 运用DirectoryInfo类和FileInfo类
    C# 文件操作概述
    LINUX介绍
    linux iso 下载地址
    ADO.NET梳理
  • 原文地址:https://www.cnblogs.com/wang-hesong/p/11378159.html
Copyright © 2011-2022 走看看