zoukankan      html  css  js  c++  java
  • 斜率优化

    斜率优化

    斜率优化是个难点,或许做多了就好了吧。

    还是和各种DP优化一样,我们先想出比较暴力的转移方程:f[i] = max{f[j] + xxx},如果发现xxx里有i的相关项与j的相关项相乘的话,就可能是斜率优化了。

    我们通常以j的相关项为横坐标,f[j]为纵坐标,把候选决策集合(点集)表示出来,再把f[j]用j的相关项和i的相关项表示出来,如果发现f[j] = xxx是斜率已知的直线,纵截距代表f[i],那么用斜率优化就基本没错了。

    例题:301. 任务安排2

    正好遇到这道题就说一下:如果某个状态进行某种决策后,其对后的影响已知,不妨让状态顺便包含一下该影响。这种思想叫“费用提前计算”(by lyd)

    如这道例题,状态f[i]如果表示将前i件任务分批处理所需最小费用(含S对以后的影响),那么这道题将由n³降到n²。

    代码:

    struct vectors{
    	int x;
    	int y;
    	vectors(int xx = 0, int yy = 0){x = xx, y = yy;}
    	vectors operator +(const vectors a)const {
    		return vectors(x + a.x, y + a.y);
    	}
    	vectors operator -(const vectors a)const {
    		return vectors(x - a.x, y - a.y);
    	}
    	int operator *(const vectors a)const {
    		return x * a.y - y * a.x;
    	}
    }q[N << 2], xl;
    int main() {
    	...
    	for (register int i = 1; i <= n; ++i) {
    		tmp = s * csum[n] + tsum[i] * csum[i];
    		f[i] = tmp;
    		xl = vectors(1, s + tsum[i]);
    		while (front + 1 < rear && (q[front + 2] - q[front + 1]) * xl >= 0)	front++;
    		if (front < rear)	f[i] = min(f[i], tmp + q[front + 1].y - q[front + 1].x * (s + tsum[i]));
    		xl = vectors(csum[i], f[i]);
    		while (front < rear - 1 && (q[rear] - q[rear - 1]) * (xl - q[rear - 1]) <= 0)	rear--;
    		q[++rear] = xl;
    	}
        
    	printf("%lld
    ", f[n]);
    }
    

    注意!!

    写正常斜率优化的第二个While(取答案)时,一定记得... * (xl - q[rear - 1])而不是... * xl!!(计算几何没学好)

    果然计算几何没学好

    斜率优化的第二个While(取答案)时,是(stk[] - stk[]) * xl而不是(stk[] - stk[]) * (stk[] + xl)!!!

    注意斜率是 xl(1, ...),而不是 xl(...)

    注意计算几何要用 <= 而不要用 <。

  • 相关阅读:
    小笔记系列——Excel中获取当前日期
    Git 错误:OpenSSL SSL_read: Connection was reset, errno 10054
    cmd_切换文件目录的几种方法
    Jupyter Notebook 常用操作(持续更新中……)
    chrome 浏览器书签保存
    各种开发工具注释的快捷键(持续更新中…)
    Spyder 快捷键(注释、跳转、缩进)
    ISlide插件安装后,PPT无法正常关闭
    [TimLinux] 操作系统实战45讲
    [TimLinux] vnc and go bashrc
  • 原文地址:https://www.cnblogs.com/JiaZP/p/13320906.html
Copyright © 2011-2022 走看看