zoukankan      html  css  js  c++  java
  • [APIO2010]特别行动队

    解析

    转移方程很容易推:(f_i = max(f_j + a * (s_i - s_j)^2 + b * (s_i - s_j) + c))
    然后当 (j>k) 时,如果 (j) 更优
    那么 (f_j + a * (s_i - s_j)^2 + b * (s_i - s_j) + c > f_k + a * (s_i - s_k)^2 + b * (s_i - s_k) + c)
    整理得:((f_j + a * s_j^2 - b * s_j) - (f_k + a * s_k^2 - b * s_k) > 2 * a * s_i * (s_j-s_k))
    因为 (s_j-s_k) 大于零
    所以我们可以把不等式两边同除 (s_j-s_k) (不除 (2*a),当然也可以除,但注意 (a < 0),除过去要变号)
    于是就成了

    [frac{(f_j + a imes s_j^2 - b imes s_j) - (f_k + a imes s_k^2 - b imes s_k)}{s_j-s_k} > 2 a imes s_i ]

    既然是大于号,那么维护上凸壳
    右边单调减,单调队列维护即可

    (Code)

    #include<cstdio>
    using namespace std;
    typedef long long LL;
    
    const int N = 1e6 + 5;
    int n , l , r;
    LL a , b , c , f[N] , q[N] , s[N];
    
    double slope(int u , int v)
    { 
    	return 1.0 * ((f[u] + a * s[u] * s[u] - b * s[u]) - (f[v] + a * s[v] * s[v] - b * s[v])) 
    		/ (s[u] - s[v]);
    }
    
    int main()
    {
    	scanf("%d%lld%lld%lld" , &n , &a , &b , &c);
    	for(register int i = 1; i <= n; i++) scanf("%lld" , &s[i]) , s[i] += s[i - 1];
    	q[l = r = 1] = 0;
    	for(register int i = 1; i <= n; i++)
    	{
    		while (l < r && slope(q[l] , q[l + 1]) > 2.0 * a * s[i]) l++;
    		f[i] = f[q[l]] + a * (s[i] - s[q[l]]) * (s[i] - s[q[l]]) + b * (s[i] - s[q[l]]) + c;
    		while (r >= l && slope(q[r] , q[r - 1]) < slope(q[r] , i)) r--;
    		q[++r] = i;
    	}
    	printf("%lld" , f[n]);
    }
    
  • 相关阅读:
    Java基本数据类型转换
    Java中的数据类型
    Java常见关键字
    HashMap源码分析(jdk 8)
    函数参数
    存储盘在系统中对应的naa号
    Python处理文本换行符
    Python文件操作中的方法:.write()换行
    此示例示意标准输出函数print的用法
    主机端查看到的wwpn 不是以:分割解决办法
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/13684501.html
Copyright © 2011-2022 走看看