zoukankan      html  css  js  c++  java
  • bzoj 1010: [HNOI2008]玩具装箱toy

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1010

    学习斜率dp的话请翻看我的 dp斜率优化小计

    递推公式:f[i]=min(f[j]+(i-j-1+sum[i]-sum[j]-L)^2) , j<i

    令g[i]=sum[i]+i, c=L+1

    有f[i]=min(f[j]+(g[i]-g[j]-L)^2), j<i

    展开,化成f[i]=min(-a[i]*x[j]+y[j])+w[i]形式有:

    a[i]=2*g[i]

    x[j]=g[j]

    y[j]=f[j]+g[j]^2+2*g[j]*c

    可以看出,a[i]与(x[j], y[j])均为增序列

    那么用单调队列维护凸包就好了

     1 /*
     2  * Problem:  BZOJ 1010
     3  * Author:  SHJWUDP
     4  * Created Time:  2015/4/28 星期二 14:09:04
     5  * File Name: 233.cpp
     6  * State: Accepted
     7  * Memo: 斜率优化dp
     8  */
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <algorithm>
    13 
    14 using namespace std;
    15 
    16 typedef long long int64;
    17 typedef unsigned long long int65;
    18 
    19 const int MaxA=5e4+7;
    20 
    21 int N, L;
    22 int C[MaxA];
    23 int64 sum[MaxA], g[MaxA];
    24 int64 f[MaxA];
    25 int deque[MaxA];
    26 inline int64 getDX(int i, int j) {
    27     return g[i]-g[j];
    28 }
    29 inline int64 getDY(int i, int j) {
    30     return (f[i]+g[i]*g[i]+2*(L+1)*g[i])-(f[j]+g[j]*g[j]+2*(L+1)*g[j]);
    31 }
    32 inline int64 cal(int i, int j) {
    33     return f[j]+(g[i]-g[j]-(L+1))*(g[i]-g[j]-(L+1));
    34 }
    35 void solve() {
    36     f[0]=0;
    37     int front=0, tail=0;
    38     deque[tail++]=0;
    39     for(int i=1; i<=N; i++) {
    40         //如果单调队列中第后一个比前一个更优,那么舍弃前一个
    41         while(front+1<tail && cal(i, deque[front+1])<=cal(i, deque[front])) front++;
    42         f[i]=cal(i, deque[front]);
    43         //维护下凸包
    44         while(front+1<tail && 
    45                 getDY(i, deque[tail-1])*getDX(deque[tail-1], deque[tail-2])
    46                 <= getDY(deque[tail-1], deque[tail-2])*getDX(i, deque[tail-1])) tail--;
    47         deque[tail++]=i;
    48     }
    49     printf("%lld
    ", f[N]);
    50 }
    51 int main() {
    52 #ifndef ONLINE_JUDGE
    53     freopen("in", "r", stdin);
    54     //freopen("out", "w", stdout);
    55 #endif
    56     while(~scanf("%d%d", &N, &L)) {
    57         sum[0]=0;
    58         for(int i=1; i<=N; i++) {
    59             scanf("%d", &C[i]);
    60             sum[i]=sum[i-1]+C[i];
    61             g[i]=sum[i]+i;
    62         }
    63         solve();
    64     }
    65     return 0;
    66 }
    bzoj 1010
  • 相关阅读:
    织梦会员注册邮箱验证发送邮件配置教程
    垃圾回收
    0910
    0909
    vs2008 打包中添加卸载工具
    CLR
    委托
    软考之存储方式
    软考之面向对象-关系
    软考之合同法
  • 原文地址:https://www.cnblogs.com/shjwudp/p/4463321.html
Copyright © 2011-2022 走看看