• bzoj 1096: [ZJOI2007]仓库建设


    和刚做的一样,写出一个f[i]分别从f[j],f[k](i>j>k)的方程,然后令f[j]<f[k],得到的是一个f[j]-f[k]<cost(i,k)-cost(i,j),然后可以发现每个点到i的价值可以用x[i]*p[j]-x[j]*p[j]的到,那么都写出来,提一下x[i],就可以把p[j],和p[j]*x[j]搞一个前缀和来维护啦。

    (这些题还是都开了LL靠谱。。)

     1 #include <bits/stdc++.h>
     2 #define LL long long
     3 #define lowbit(x) x&(-x)
     4 #define inf 0x3f3f3f3f
     5 #define eps 1e-5
     6 #define N 1000005
     7 using namespace std;
     8 inline int ra()
     9 {
    10     int x=0,f=1; char ch=getchar();
    11     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    12     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    13     return x*f;
    14 }
    15 LL f[N],cst[N],a[N];
    16 int x[N],p[N],c[N],q[N];
    17 int n;
    18 double slope(int j, int k)
    19 {
    20     return (double)(f[j]-f[k]+(a[j]-a[k]))/(double)(cst[j]-cst[k]);
    21 }
    22 int main(int argc, char const *argv[])
    23 {
    24     n=ra();
    25     for (int i=1; i<=n; i++) x[i]=ra(),p[i]=ra(),c[i]=ra();
    26     for (int i=1; i<=n; i++) cst[i]=p[i]+cst[i-1];
    27     for (int i=1; i<=n; i++) a[i]=a[i-1]+p[i]*x[i];
    28     int l=0,r=0;
    29     for (int i=1; i<=n; i++)
    30     {
    31         while (l<r && slope(q[l+1],q[l])<x[i]) l++;
    32         int t=q[l];
    33         f[i]=f[t]+c[i]+x[i]*(cst[i]-cst[t])-(a[i]-a[t]);
    34         while (l<r && slope(i,q[r])<slope(q[r],q[r-1])) r--;
    35         q[++r]=i;
    36     }
    37     cout<<f[n];
    38     return 0; 
    39 }
  • 相关阅读:
    491 · 回文数
    936 · 首字母大写
    1343 · 两字符串和
    1535 · 转换成小写字母
    13 · 字符串查找
    146 · 大小写转换 II
    241 · 转换字符串到整数(容易版)
    46 · 主元素
    kotlin协程——>通道
    kotlin协程——>异步流
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6523062.html
Copyright © 2020-2023  润新知