1610:玩具装箱

时间限制: 1000 ms         内存限制: 524288 KB

【题目描述】

原题来自:HNOI 2008

P 教授要去看奥运,但是他舍不得他的玩具,于是他决定把所有的玩具运到北京。

他使用自己的压缩器进行压缩。这个压缩器可以将任意物品变成一维,再放到一种特殊的一维容器中。P 教授有编号为 i 。

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

在一个一维容器中,玩具的编号是连续的;

如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物。形式地说,如果要将 

制作容器的费用与容器的长度有关,根据教授研究,如果容器长度为 L是一个常量。

P 教授不关心容器的数目,他可以制作出任意长度的容器,甚至超过 。试求最小费用。

【输入】

第一行输入两个整数 ,L;

接下来 Ci 。

【输出】

输出最小费用。

【输入样例】

5 4
3
4
2
1
4

【输出样例】

1

【提示】

数据范围与提示:

对于全部数据,1≤N≤5×104,1≤L,Ci≤10

 

sol:这题关键是暴力要写的尽量简洁些,式子才好推。。。

考虑如何使转移尽量简洁,Qzh[i]=Cost(1~i),使得Costi+=i,但这样会使得每次多一个,怎么办,把L+1就好了

方程就简洁了 dp[i]=dp[j]+Sqr(Qzh[i]-Qzh[j]-L),这样就很好推了

推出 j<k<i时 (为简洁把Qzh称作S)

若 dp[k]+S[k]2-dp[j]-S[j]2<=(S[i]-L)*(2*(S[k]-S[j]))成立,则 k 比 j 优

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read()
{
    ll s=0;
    bool f=0;
    char ch=' ';
    while(!isdigit(ch))
    {
        f|=(ch=='-'); ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0)
    {
        putchar('-'); x=-x;
    }
    if(x<10)
    {
        putchar(x+'0'); return;
    }
    write(x/10);
    putchar((x%10)+'0');
    return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=50005;
int n,L;
ll Qzh[N];
ll dp[N];
inline ll Sqr(ll x)
{
    return x*x;
}
int main()
{
    int i,j;
    R(n); L=read()+1;
    for(i=1;i<=n;i++)
    {
        Qzh[i]=Qzh[i-1]+read();
    }
    for(i=1;i<=n;i++)
    {
        Qzh[i]+=i;
    }
    memset(dp,63,sizeof dp); dp[0]=0;
    for(i=1;i<=n;i++)
    {
        for(j=0;j<i;j++)
        {
            dp[i]=min(dp[i],dp[j]+Sqr(Qzh[i]-Qzh[j]-L));
        }
    }
    Wl(dp[n]);
    return 0;
}
/*
input
5 4
3
4
2
1
4
output
1
*/
暴力代码

相关文章:

  • 2022-01-18
  • 2021-06-04
  • 2021-11-20
  • 2021-06-29
  • 2021-07-01
猜你喜欢
  • 2022-01-14
  • 2021-11-17
  • 2021-05-28
  • 2022-12-23
  • 2021-08-11
  • 2021-04-08
  • 2021-11-08
相关资源
相似解决方案