• BZOJ1010: [HNOI2008]玩具装箱toy



    BZOJ1010: [HNOI2008]玩具装箱toy##

      Time Limit: 1 Sec
      Memory Limit: 162 MB

    Description###

      P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京。他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中。P教授有编号为1...N的N件玩具,第i件玩具经过压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的。同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一个容器中,那么容器的长度将为 x=j-i+Sigma(Ck) i<=K<=j 制作容器的费用与容器的长度有关,根据教授研究,如果容器长度为x,其制作费用为(X-L)^2.其中L是一个常量。P教授不关心容器的数目,他可以制作出任意长度的容器,甚至超过L。但他希望费用最小.
     

    Input###

       第一行输入两个整数N,L.接下来N行输入Ci.1<=N<=50000,1<=L,Ci<=10^7
     

    Output###

       输出最小费用
     

    Sample Input###

      5 4
      3
      4
      2
      1
      4
     

    Sample Output###

      1
        

    HINT

    题目地址:BZOJ1010: [HNOI2008]玩具装箱toy

    题目大意: 做的心烦意乱,不写了

    题解:

      by hzw
      $$dp[i]=min(dp[j]+(sum[i]-sum[j]+i-j-1-L)^2) (j<i)$$
       (f[i]=sum[i]+i,c=1+l)
       (dp[i]=min(dp[j]+(f[i]-f[j]-c)^2))
      1.证明决策单调性
      假设在状态 (i) 处的 (k) 决策优与 (j) 决策,即
      $$dp[k]+(f[i]-f[k]-c)2<=dp[j]+(f[i]-f[j]-c)2$$
      则对于 (i) 后的所有状态 (t),要证明决策单调性
       (dp[k]+(f[t]-f[k]-c)^2<=dp[j]+(f[t]-f[j]-c)^2)
      只要证
      $$dp[k]+(f[i]+v-f[k]-c)2<=dp[j]+(f[i]+v-f[j]-c)2$$
      只要证
      $$dp[k]+(f[i]-f[k]-c)2+2*v*(f[i]-f[k]-c)+v2<=dp[j]+(f[i]-f[j]-c)2+2*v*(f[i]-f[j]-c)+v2$$
      只要证
      $$2v(f[i]-f[k]-c)<=2v(f[i]-f[j]-c)$$
       (f[k]>=f[j])(显然)
      证明完毕
      2.求斜率方程
      因为 (dp[k]+(f[i]-f[k]-c)^2<=dp[j]+(f[i]-f[j]-c)^2)
      展开
      $$dp[k]+f[i]2-2*f[i]*(f[k]+c)+(f[k]+c)2<=dp[j]+f[i]2-2*f[i]*(f[j]+c)+(f[j]+c)2$$
      
      $$dp[k]-2f[i](f[k]+c)+(f[k]+c)2<=dp[j]-2*f[i]*(f[j]+c)+(f[j]+c)2$$
       ((dp[k]+(f[k]+c)^2-dp[j]-(f[j]+c)^2)/2*(f[k]-f[j])<=f[i])
      (f[i]) 是单调递增的,我们使用队列维护一个下凸壳,每次取出队头作为决策
      加入决策 (i) 时,令队尾为 (q[r])前一个为 (q[r-1])
      满足 (斜率 (q[r],i) < 斜率(q[r-1],q[r])) 时,显然队尾是无效的,将其弹出
      具体看代码
      还有一位dalao写得超级好懂
      大米饼


    AC代码

    #include <stdio.h>
    #define ll long long
    using namespace std;
    const int N=5e4+5;
    int n,L;
    int q[N];
    ll s[N],dp[N];
    inline double X(int i){
    	return s[i];
    }
    inline double Y(int i){
    	return dp[i]+(s[i]+L)*(s[i]+L); 
    }
    inline double rate(int i,int k){
    	return (Y(k)-Y(i))/(X(k)-X(i));
    }
    int main(){
    	scanf("%d%d",&n,&L);L++;
    	for(int i=1;i<=n;i++){
    		scanf("%lld",&s[i]);
    		s[i]+=s[i-1];
    	}
    	for(int i=1;i<=n;i++)
    		s[i]+=i;
    	int l=1,r=1;q[1]=0;
    	for(int i=1;i<=n;i++){
    		while(l<r && rate(q[l],q[l+1])<2*s[i])l++;
    		int t=q[l];
    		dp[i]=dp[t]+(s[i]-s[t]-L)*(s[i]-s[t]-L);
    		while(l<r && rate(q[r-1],q[r])>rate(q[r],i))r--;
    		q[++r]=i;
    	}
    	printf("%lld
    ",dp[n]);
    	return 0;
    }
    


      作者:skl_win
      出处:https://www.cnblogs.com/shaokele/
      本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    jchdl
    jchdl
    UVa 10256 (判断两个凸包相离) The Great Divide
    UVa 11168 (凸包+点到直线距离) Airport
    LA 2572 (求可见圆盘的数量) Kanazawa
    UVa 10652 (简单凸包) Board Wrapping
    UVa 12304 (6个二维几何问题合集) 2D Geometry 110 in 1!
    UVa 10674 (求两圆公切线) Tangents
    UVa 11796 Dog Distance
    LA 3263 (平面图的欧拉定理) That Nice Euler Circuit
  • 原文地址:https://www.cnblogs.com/shaokele/p/9594552.html
Copyright © 2020-2023  润新知