码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-05-30 00:30:36      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:

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\n",ans);
  return 0; 
}

 

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

标签:

原文地址:http://www.cnblogs.com/Xiper/p/4539610.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!