码迷,mamicode.com
首页 > 其他好文 > 详细

[ZJOI2007]仓库建设

时间:2019-12-20 14:02:58      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:rac   display   zjoi   lin   register   zjoi2007   建设   复杂度   typedef   

以前学斜率优化觉得好难

现在莫名觉得简单 (雾)

\(fee[i]\)维护的一个前缀和

\(sum[i]\)维护的成品的前缀和

\(dis[i]\)维护\(0->i\)的距离

易得状态转移方程

\[dp[i] = min(dp[i],dp[j] + fee[i] - fee[j] - sum[j] * (dis[i] - dis[j]) + cost[i]);\]

时间复杂度 \(O(n^2)\) \(n_{max}=1e6\) \(TlE\)

考虑优化

方程中有乘积

考虑斜率优化

易得

\[\frac{dp[j] - fee[j] + sum[j] * dis[j] - (dp[k] - fee[k] + sum[k] * dis[k])}{(sum[j] - sum[k])}<dis[i]\]

\(Code\)

#include <set>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define reg register int
#define isdigit(x) ('0' <= x&&x <= '9')
template<typename T>
inline T Read(T Type)
{
    T x = 0,f = 1;
    char a = getchar();
    while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
    while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();}
    return x * f;
}
const int MAXN = 1e6 + 10;
int q[MAXN];
typedef long long ll;
ll sum[MAXN],dp[MAXN],dis[MAXN],fee[MAXN],cost[MAXN];
#define M(x) (x) * (x)
inline ll Get(int j,int k)
{
    return dp[j] - fee[j] + sum[j] * dis[j] - (dp[k] - fee[k] + sum[k] * dis[k]);
}
inline ll Get2(int j,int k)
{
    return sum[j] - sum[k];
}
inline ll Getdp(int i,int j)
{
    return dp[j] + fee[i] - fee[j] - sum[j] * (dis[i] - dis[j]) + cost[i];
}
int main()
{
//  dp[j] - fee[j] - sum[j] * (dis[i] - dis[j]) < 
//  dp[k] - fee[k] - sum[k] * (dis[i] - dis[k])
//  dp[j] - fee[j] + sum[j] * dis[j] - (dp[k] - fee[k] + sum[k] * dis[k])  < (sum[j] - sum[k]) * dis[i]
    int n = Read(1);
    for(reg i = 1;i <= n;i++)
    {
        int x = Read(1),p = Read(1),c = Read(1);
        dis[i] = x,sum[i] = sum[i - 1] + p,cost[i] = c;
        fee[i] = fee[i - 1] + (dis[i] - dis[i - 1]) * sum[i - 1];
    }
//  memset(dp,0x3f3f3f,sizeof(dp));
//  dp[0] = 0;
//  for(reg i = 1;i <= n;i++)
//  {
//      for(reg j = 0;j < i;j++)
//      {
//          dp[i] = min(dp[i],dp[j] + fee[i] - fee[j] - sum[j] * (dis[i] - dis[j]) + cost[i]);
//      }
//  }
//  printf("%lld\n",dp[n]);
    int head = 0,tail = 1;
    for(reg i = 1;i <= n;i++)
    {
        while(head + 1 < tail&&1.0 * Get(q[head + 1],q[head]) / Get2(q[head + 1],q[head]) <= dis[i])
            head++;
        dp[i] = Getdp(i,q[head]);
        while(head + 1 < tail&&1.0 * Get(i,q[tail - 1]) / Get2(i,q[tail - 1]) <= 1.0 * Get(q[tail - 1],q[tail - 2]) / Get2(q[tail - 1],q[tail - 2]))
            tail--;
        q[tail] = i;
        tail++;
    }
    printf("%lld\n",dp[n]);
    return 0;
}

\(Solution\) \(II\)

考虑决策单调性

证明略

[ZJOI2007]仓库建设

标签:rac   display   zjoi   lin   register   zjoi2007   建设   复杂度   typedef   

原文地址:https://www.cnblogs.com/resftlmuttmotw/p/12072608.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!