• UESTC_酱神赏花 2015 UESTC Training for Dynamic Programming<Problem C>


    C - 酱神赏花

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 262143/262143KB (Java/Others)
     

    酱神去杭州赏花。

    花展在一条街道上举行,这条街道上有一共有n个节点,自左而右从1n编号,1号和n号是左右两个端点,两个相邻端点之间的距离为1.本次花展一共要展出m朵花,在第ti时刻,有一朵颜值为bi的花将在第ai个节点展出,如果酱神在ti时刻处于第x个节点,那么他能获得的开心值为bi|xai|,注意这个值可能为负。

    t=1的时刻,酱神可以随意从1n选出一个节点作为赏花的起点。在接下来的每个单位时间段中,酱神最多能移动d的距离。酱神每秒只能移动整数个距离,且任何时刻不能超出街道的范围。

    他能获得的最大开心值为多少?

    Input

    第一行3个数n,m,d

    接下来m行,每行3个数ai,bi,ti

    1n105,1m100

    1ain

    1bi109

    1ti109

    1d109

    Output

    输出一个数,酱神的最大开心值。

    Sample input and output

    Sample InputSample Output
    30 4 2
    27 3 1
    11 4 1
    11 4 1
    1 2 20
    
    -3
    

    解题思路:

    我们令f( i , j ) -> 目前第 j 朵花开,酱神正在坐标点 i 的最小花费.

     我们考虑转移

     F ( i , j ) = min ( F( u , j - 1) – abs( i – u ) ) + B[j]

     不妨令 i > u

     有

     F( i ,j ) = min ( F( u , j – 1 ) ) + B[j] + u – i;

     当i < u时同理

     这样

     我们维护一个单调队列即可,正反跑两遍即可.

     

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    
    typedef long long ll;
    using namespace std;
    const int maxn = 1e5 + 50;
    ll f[maxn][2];
    int cur = 0 , q[maxn];
    ll n,m,d;
    
    typedef struct flower
    {
      ll a,b,t;
      friend bool operator < (const flower & x,const flower & y)
       {
             return x.t < y.t;
       }
    };
    
    flower A[100+10];
    
    void init_f()
    {
       for(int i = 0 ; i <= n ; ++ i)
        f[i][cur] = -999999999999999;
    }
    
    int main(int argc,char *argv[])
    {
      scanf("%d%d%d",&n,&m,&d);
      for(int i = 1 ; i <= m ; ++ i)
       scanf("%d%d%d",&A[i].a,&A[i].b,&A[i].t);
      sort(A+1,A+1+m);
      for(int i = 1 ; i <= n ; ++ i)
       f[i][cur] = A[1].b - abs(i - A[1].a);
      for(int j = 2 ; j <= m ; ++ j)
       {
             ll limit = (A[j].t - A[j-1].t)*d;
             cur ^= 1;
             int front = 0 , rear = 0;
             init_f();
             for(int i = 1 ; i <= n ; ++ i)
              {
                 while(rear > front && f[i][cur^1] >= f[q[rear-1]][cur^1])
                rear--;
              q[rear++] = i;
              while(rear > front && (i - q[front]) > limit)
                front++;
              f[i][cur] = max(f[i][cur],f[q[front]][cur^1] + A[j].b - abs(i - A[j].a));
           }
          front = 0 , rear = 0;
          for(int i = n ; i >= 1 ; -- i)
           {
                 while(rear > front && f[i][cur^1] >= f[q[rear-1]][cur^1])
                  rear--;
              q[rear++] = i;
              while(rear > front && (q[front] - i) > limit)
                front++;
              f[i][cur] = max(f[i][cur],f[q[front]][cur^1] + A[j].b - abs(i - A[j].a));
           }
       } 
      ll ans = -9999999999999999;
      for(int i = 1 ; i <= n ; ++ i)
       ans = max(ans,f[i][cur]);
      printf("%lld
    ",ans);
      return 0; 
    }
    No Pain , No Gain.
  • 相关阅读:
    mybatis的xml文件中的CDATA的使用
    使用jedis执行lua脚本
    连接池中的maxIdle,MaxActive,maxWait等参数详解
    Unity3D脚本中文系列教程(十六)
    Unity3D脚本中文系列教程(十五)
    Unity3D脚本中文系列教程(十四)
    Unity3D脚本中文系列教程(十三)
    Unity3D脚本中文系列教程(十二)
    Unity3D脚本中文系列教程(十一)
    Unity3D脚本中文系列教程(十)
  • 原文地址:https://www.cnblogs.com/Xiper/p/4539610.html
Copyright © 2020-2023  润新知