zoukankan      html  css  js  c++  java
  • 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/
      本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    MyBatis框架浅析之 缓存
    MyBatis框架浅析之 Mapper.xml 映射文件
    MyBatis框架浅析之 XML配置文件
    MySQL安装
    C语言内存分配
    二叉树性质
    pycharm使用anaconda的python环境
    linux删除文件夹、文件名字转码、java转码、json字符报错、查看当前系统编码、传代码至git
    java 性能优化
    java 建maplist放case center合并
  • 原文地址:https://www.cnblogs.com/shaokele/p/9594552.html
Copyright © 2011-2022 走看看