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

    题意简述

    将n个士兵分为若干组,每组连续,编号为i的士兵战斗力为xi
    若i~j士兵为一组,该组初始战斗力为( s = sumlimits_{k = i}^{j}xk ),实际战斗力(a * s^2 + b * s + c)(a,b,c为常数)
    求最大实际战斗力

    题解思路

    ( dp[i] = max(dp[j) + a * (s[i] - s[j]) ^ 2 + b * (s[i] - s[j]) + c )
    然后斜率优化,单调队列维护

    代码

    #include <cstdio>
    using namespace std;
    typedef long long ll;
    int n, l, h, t, a, b, c;
    int q[1000010];
    ll sum[1000010], dp[1000010];
    ll sqr(ll x) {return x * x; }
    int s1(int x) {return sum[x] * 2 * a; }
    int s2(int x) {return sum[x]; }
    int s4(int x) {return dp[x] + a * sqr(s2(x)) - b * s2(x); }
    double calc(int i, int j) {return (double)(s4(j) - s4(i)) / (s2(j) - s2(i)); }
    int main()
    {
    	scanf("%d", &n);
    	scanf("%d%d%d", &a, &b, &c);
    	for (register int i = 1; i <= n; ++i)
    	{
    		scanf("%d", &sum[i]);
    		sum[i] += sum[i - 1];
    	}
    	h = t = 1;
    	for (register int i = 1; i <= n; ++i)
    	{
    		while (h < t && calc(q[h], q[h + 1]) > s1(i)) ++h;
    		dp[i] = s4(q[h]) - s1(i) * s2(q[h]) + a * sqr(s2(i)) + b * s2(i) + c;
    		while (h < t && calc(q[t - 1], q[t]) < calc(q[t], i)) --t;
    		q[++t] = i;
    	}
    	printf("%lld
    ", dp[n]);
    }
    
  • 相关阅读:
    Android安装apk
    Android获取应用程序版本信息
    Handler消息传递机制
    Activity的启动模式
    cocopods的使用
    ios9 的新特性
    静态库的制作详解
    真机调试
    时间差计算(给定两时间,转换为时间差)
    socket 通信机制的实现
  • 原文地址:https://www.cnblogs.com/xuyixuan/p/9467530.html
Copyright © 2011-2022 走看看