zoukankan      html  css  js  c++  java
  • 【APIO2010T1】特别行动队-DP斜率优化

    测试地址:特别行动队

    做法:这题需要用到DP斜率优化。

    设f[i]为拆分前i个士兵可获得的最大战斗力,sum[i]为前i个士兵的初始战斗力之和,很容易得到O(N^2)的方程:

    f[i]=max{f[j]+a(sum[i]-sum[j])^2+b(sum[i]-sum[j])+c}(0≤j<i)

    然而N可达1000000,我们需要考虑优化。

    我们把max内部的式子展开得:f[j]+a*sum[i]^2-2*a*sum[i]*sum[j]+a*sum[j]^2+b*sum[i]-b*sum[j]+c,把a*sum[i]^2+b*sum[i]+c这些无关项从max中取出来,则剩下的式子G=-2*a*sum[i]*sum[j]+f[j]+a*sum[j]^2-b*sum[j],令k=2*a*sum[i],x=sum[j],y=f[j]+a*sum[j]^2-b*sum[j],则G=-kx+y,所以y=kx+G。要求G的最大值,就是求一条斜率为k的直线与前面状态点上凸壳的切点。由于sum单调递增,a是负数,所以x单调递增,k单调递减,所以可以用单调队列维护上凸壳,复杂度优化到O(N),完美解决该问题。

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    int n,h,t,q[1000010];
    long long a,b,c,sum[1000010],f[1000010];
    struct point
    {
      long long x,y;
      point operator - (point a) const
      {
        point s;
    	s.x=x-a.x;
    	s.y=y-a.y;
    	return s;
      }
    }p[1000010];
    
    long long multi(point a,point b)
    {
      return a.x*b.y-b.x*a.y;
    }
    
    void solve()
    {
      h=1,t=1;
      q[1]=0;p[0].x=p[0].y=0;
      for(int i=1;i<=n;i++)
      {
        point now;
    	now.x=1,now.y=2*a*sum[i];
        while(h<t&&multi(now,p[q[h+1]]-p[q[h]])>=0) h++;
    	int j=q[h];
    	f[i]=f[j]+a*(sum[i]-sum[j])*(sum[i]-sum[j])+b*(sum[i]-sum[j])+c;
    	p[i].x=sum[i],p[i].y=f[i]+a*sum[i]*sum[i]-b*sum[i];
    	while(h<t&&multi(p[i]-p[q[t-1]],p[q[t]]-p[q[t-1]])<=0) t--;
    	q[++t]=i;
      }
    }
    
    int main()
    {
      scanf("%d",&n);
      scanf("%lld%lld%lld",&a,&b,&c);
      sum[0]=0;
      for(int i=1;i<=n;i++)
      {
        long long a;
    	scanf("%lld",&a);
    	sum[i]=sum[i-1]+a;
      }
      
      solve();
      printf("%lld",f[n]);
      
      return 0;
    }
    


  • 相关阅读:
    HMM 学习一
    matlab buffer的使用
    JDK环境变量配置及Tomcat安装服务
    Js参数RSA加密传输,jsencrypt.js的使用
    Dapper基本增删改查
    Dapper事务操作
    Ubuntu知识记录
    InstallShield 覆盖安装
    Limited Edition for Visual Studio 2013 图文教程(教你如何打包.NET程序)
    Sql Server导出表结构Excel
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793706.html
Copyright © 2011-2022 走看看