zoukankan      html  css  js  c++  java
  • Luogu P3195 [HNOI2008]玩具装箱

    题目
    预处理(C)的前缀和(sum)。设前(i)个物品的最小答案为(f)
    (f_i=maxlimits_{jin[1,i)}(f_j+(sum_i-sum_j-L)^2))
    拆开就是(f_i=maxlimits_{jin[1,i)}(f_j+sum_i^2+sum_j^2+L^2-2Lsum_i-2Lsum_j-2sum_isum_j))
    稍微整理一下(f_i=maxlimits_{jin[1,i)}(f_j+sum_j^2-2Lsum_j-2sum_isum_j)+sum_i^2+L^2-2Lsum_i)
    然后直接斜率优化。
    代码是以前写的,建议斜率交叉相乘后判断大小避免精度误差。

    #include<bits/stdc++.h>
    #define N 50001
    using namespace std;
    inline int read()
    {
        int x=0;
        char ch=getchar();
        while(ch<'0'||ch>'9')
            ch=getchar();
        while(ch>='0'&&ch<='9')
            x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
        return x;
    }
    inline int max(int a,int b)
    {
    	return a>b? a:b;
    }
    long long sum[N],f[N],q[N],L;
    inline double slope(int i,int j)
    {
    	return (double)(f[i]-f[j]+(sum[i]-sum[j])*(sum[i]+sum[j]+(L<<1)))/(double)(sum[i]-sum[j]);
    }
    int main()
    {
    	register int n=read();
    	L=read()+1;
    	for(register int i=1;i<=n;++i)
    		sum[i]=sum[i-1]+read()+1;
    	register int hd=1,tl=1;
    	for(register int i=1;i<=n;++i)
    	{
    		while(hd<tl&&slope(q[hd],q[hd+1])<2*sum[i])
    			++hd;
    		f[i]=f[q[hd]]+(sum[i]-sum[q[hd]]-L)*(sum[i]-sum[q[hd]]-L);
            while(hd<tl&&slope(i,q[tl-1])<slope(q[tl-1],q[tl]))
    			--tl;
            q[++tl]=i;
        }
        return printf("%lld",f[n]),0;
    }
    
  • 相关阅读:
    android 设置时间和日期
    android 对话框
    android notification 通知
    android 动画(转载)
    js的作用域题
    js高级
    js中级6
    js中级小知识5
    js中级小知识4
    js中级小知识3
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11749595.html
Copyright © 2011-2022 走看看