zoukankan      html  css  js  c++  java
  • UESTC_我要长高 CDOJ 594

    韩父有N个儿子,分别是韩一,韩二…韩N。由于韩家演技功底深厚,加上他们间的密切配合,演出获得了巨大成功,票房甚至高达2000万。舟子是名很有威望的公知,可是他表面上两袖清风实则内心阴暗,看到韩家红红火火,嫉妒心遂起,便发微薄调侃韩二们站成一列时身高参差不齐。由于舟子的影响力,随口一句便会造成韩家的巨大损失,具体亏损是这样计算的,韩一,韩二…韩N站成一排,损失即为C×(韩i与韩i+1的高度差(1i<N))之和,搞不好连女儿都赔了.韩父苦苦思索,决定给韩子们内增高(注意韩子们变矮是不科学的只能增高或什么也不做),增高1cm是很容易的,可是增高10cm花费就很大了,对任意韩i,增高Hcm的花费是H2.请你帮助韩父让韩家损失最小。

    Input

    有若干组数据,一直处理到文件结束。

    每组数据第一行为两个整数:韩子数量N(1N50000)和舟子系数C(1C100)

    接下来N行分别是韩i的高度(1hi100)。

    Output

    对每组测试数据用一行输出韩家的最小损失。

    Sample input and output

    Sample InputSample Output
    5 2
    2
    3
    5
    1
    4
    15

    解题报告

    用单调队列来优化(正解)...空间复杂度也可以优化到O(100*2)...好吧我又没有优化

    当时先用的线段树来O(log)得到最优解,结果本机测试跑极限数据1.5s+才出。。。果断放弃(常数太大)

    之后采用rmq...交了一发TLE,彻底断了我的念头...

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    typedef long long ll;
    using namespace std;
    const int maxn = 5e4 + 500;
    int n,c,h[maxn];
    ll  q[105];
    ll  f[maxn][105];
    ll  MAX;
    
    int main(int argc,char *argv[])
    {
      MAX = 1 << 25;
      MAX *= MAX;
      while(scanf("%d%d",&n,&c) != EOF)
       {
             for(int i = 1 ; i <= n ; ++ i)
              scanf("%d",h+i);
             for(int i = 1 ; i <= n ; ++ i)
              for(int j = 1 ; j <= 100 ; ++ j)
               f[i][j] = MAX;
             for(int i = h[1] ; i <= 100 ; ++ i)
               f[1][i] = (i-h[1])*(i-h[1]);
             int front , rear ;
             for(int i = 2 ; i <= n ; ++ i)
              {
                    front = rear = 0;
                    for(int j = h[i-1] ; j <= 100 ; ++ j)
                     {
                           while(front < rear && f[i-1][q[rear-1]]-c*q[rear-1] > f[i-1][j]-c*j)
                              rear--;
                           q[rear++] = j;
               }
              for(int j = h[i] ; j <= 100 ; ++ j)
                if (j >= q[front])
                     f[i][j] = f[i-1][q[front]] - c*q[front] + c*j + (j-h[i])*(j-h[i]);
              front = rear = 0;
              for(int j = h[i-1] ; j <= 100 ; ++ j)
               {
                     while(front < rear && f[i-1][q[rear-1]]+c*q[rear-1] > f[i-1][j]+c*j )
                      rear--;
                     q[rear++] = j;
               }
              for(int j = h[i] ; j <= 100 ; ++ j)
               {
                     while(j > q[front] && front < rear)
                      front++;
                     if (q[front] >= j) 
                      f[i][j] = min(f[i][j],f[i-1][q[front]] + c*q[front] - c*j + (j-h[i])*(j-h[i]));
               }
           }
          ll ans = f[n][h[n]];
          for(int j = h[n] ; j <= 100 ; ++ j)
           ans = min(ans,f[n][j]);
          printf("%lld
    ",ans);
       }
      return 0;
    }
    No Pain , No Gain.
  • 相关阅读:
    何时使用泛型集合
    利用C#在Word自动化中操作OLE控件
    “A first chance exception of type…” Messages in VS 2005
    What is the "Could not find resource assembly" error message?
    输出PDF文档到ASP.NET页面
    Top 5 SerialPort Tips
    黑莓BlackBerry之Helloworld
    今天参加广州.NET俱乐部活动,运气超好
    全面解析EMAIL编码
    用DataView类操控数据
  • 原文地址:https://www.cnblogs.com/Xiper/p/4467718.html
Copyright © 2011-2022 走看看