首页 > Web开发 > 详细

[BZOJ4709][JSOI2011]柠檬 决策单调性优化dp

时间:2018-07-31 10:24:18      阅读:245      评论:0      收藏:0      [点我收藏+]

题解:

单调栈优化

首先发现一个性质就是

如果当前i<j 转移f[i] 比 f[j]

我们要维护一个队列保证前一个超过后一个的时间单调不减

代码:

#include <bits/stdc++.h>
using namespace std;
#define IL inline
#define ll long long
#define rint register int
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define me(x) memset(x,0,sizeof(x))
const int INF=1e9;
const int N=2e5+10;
int n;
ll f[N];
vector<int> g[N];
int s[N],a[N],cnt[N];
IL ll calc(int x,int y)
{
  return f[x-1]+1ll*a[x]*y*y;
}
IL int find(int x,int y)
{
  int h=max(s[x],s[y]),t=n;
  while(h<t)
  {
    int mid=(h+t)/2;
    if (calc(x,mid-s[x]+1)>=calc(y,mid-s[y]+1)) t=mid;
    else h=mid+1;
  }
  return(h);
}
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  ios::sync_with_stdio(false);
  cin>>n;
  rep(i,1,n)
  {
    int x;
    cin>>x;
    a[i]=x; s[i]=++cnt[x];
    int k1=g[x].size();
    while (k1>=2&&find(g[x][k1-2],g[x][k1-1])<=find(g[x][k1-1],i))
      g[x].pop_back(),k1--;
    g[x].push_back(i); k1++;
    while (k1>=2&&find(g[x][k1-2],g[x][k1-1])<=s[i]) g[x].pop_back(),k1--;
    f[i]=calc(g[x][k1-1],s[i]-s[g[x][k1-1]]+1);
  }
  cout<<f[n];
  return 0;
}

 

[BZOJ4709][JSOI2011]柠檬 决策单调性优化dp

原文:https://www.cnblogs.com/yinwuxiao/p/9393755.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!