P3195 [HNOI2008] 玩具装箱题解

题目描述

P 教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京。他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中。

P 教授有编号为 1⋯n 的 n 件玩具,第 i 件玩具经过压缩后的一维长度为 Ci​。

为了方便整理,P 教授要求:

  • 在一个一维容器中的玩具编号是连续的。

  • 同时如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物。形式地说,如果将第 i 件玩具到第 j 个玩具放到一个容器中,那么容器的长度将为 x=j−i+k=i∑j​Ck​。

制作容器的费用与容器的长度有关,根据教授研究,如果容器长度为 x,其制作费用为 (x−L)2。其中 L 是一个常量。P 教授不关心容器的数目,他可以制作出任意长度的容器,甚至超过 L。但他希望所有容器的总费用最小。

输入格式

第一行有两个整数,用一个空格隔开,分别代表 n 和 L。

第 2 到 第 (n+1) 行,每行一个整数,第 (i+1) 行的整数代表第 i 件玩具的长度 Ci​。

输出格式

输出一行一个整数,代表所有容器的总费用最小是多少。

输入输出样例

输入 #1复制

5 4
3
4
2
1
4

输出 #1复制

1

说明/提示

对于全部的测试点,1≤n≤5×104,1≤L≤107,1≤Ci​≤107。

思路

卡常n^2DP即可!!!

代码见下

#include<bits/stdc++.h>
using namespace std;
int n,l,c[50004],i,j;
long long f[50004],s,r[50004],b[50004];
int main(){
	cin>>n>>l;
    for(int i=1;i<=n;i++){
        scanf("%lld",&c[i]);
        r[i]=r[i-1]+c[i];
        b[i]=r[i]+i;
    }
    //memset(f,62,sizeof(f));
    f[0]=0;
    for(i=1;i<=n;++i){
        f[i]=1e18+7;
        for(j=0;j<=i-2;j+=2){
            s=(b[i]-b[j]-l-1);
            s*=s;
            if(s+f[j]<f[i]){
                f[i]=s+f[j];
            }
            s=(b[i]-b[j+1]-l-1);
            s*=s;
            if(s+f[j+1]<f[i]){
                f[i]=s+f[j+1];
            }
            //f[i]=min(f[i],f[j]+(b[i]-b[j]+i-j-1-l)*(b[i]-b[j]+i-j-1-l));
        }
        //if(j<i){
            s=(b[i]-b[i-1]-l-1);
            s=s*s;
            if(s+f[i-1]<f[i]){
                f[i]=s+f[i-1];
            }            
        //}
        //cout<<f[i]<<endl;
        // i++;
        // for(j=0;j<=i-2;j+=2){
        //     s=(b[i]-b[j]-l-1);
        //     s*=s;
        //     if(s+f[j]<f[i]){
        //         f[i]=s+f[j];
        //     }
        //     s=(b[i]-b[j+1]-l-1);
        //     s*=s;
        //     if(s+f[j+1]<f[i]){
        //         f[i]=s+f[j+1];
        //     }
        //     //f[i]=min(f[i],f[j]+(b[i]-b[j]+i-j-1-l)*(b[i]-b[j]+i-j-1-l));
        // }
        // //if(j<i){
        //     s=(b[i]-b[i-1]-l-1);
        //     s=s*s;
        //     if(s+f[i-1]<f[i]){
        //         f[i]=s+f[i-1];
        //     }            
        // //}
        // //cout<<f[i]<<endl;
    }
    // int i=n;
        // for(j=0;j<=i-2;j+=2){
        //     s=(b[i]-b[j]-l-1);
        //     s*=s;
        //     if(s+f[j]<f[i]){
        //         f[i]=s+f[j];
        //     }
        //     s=(b[i]-b[j+1]-l-1);
        //     s*=s;
        //     if(s+f[j+1]<f[i]){
        //         f[i]=s+f[j+1];
        //     }
        //     //f[i]=min(f[i],f[j]+(b[i]-b[j]+i-j-1-l)*(b[i]-b[j]+i-j-1-l));
        // }
        // //if(j<i){
        //     s=(b[i]-b[i-1]-l-1);
        //     s=s*s;
        //     if(s+f[i-1]<f[i]){
        //         f[i]=s+f[i-1];
        //     }            
        // //}
        // //cout<<f[i]<<endl;
    cout<<f[n]<<endl;
	return 0;
}

posted @ 2025-10-24 11:08  bz02_2023f2  阅读(3)  评论(0)    收藏  举报  来源