UVA - 1427(经典滑动队列优化dp)

首先,要说明滑动队列优化的情形,必须是当前位置前或者后面的一个连续区间的一个和 j 相关的func值。

维护的队列为一个相对有保留价值序列,如本题维护的是func值上升而里该节点的远度下降(这也是func较低而又保留价值的原因)。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <climits>
#include <deque>
using namespace std;
const int maxn = 101000;
int n,c,sum[maxn],dist[maxn],d[maxn];
int x[maxn],y[maxn],w[maxn];
int dis(int i,int j){
  return abs(x[i]-x[j])+abs(y[i]-y[j]);
}
int func(int j){
  return d[j]+sum[j]+dist[j];
}
deque<int> Q;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
      scanf("%d %d",&c,&n);
      x[0] = y[0] = sum[0] = w[0] =0;
      for(int i=1;i<=n;i++){
        int z;
        scanf("%d %d %d",&x[i],&y[i],&z);
        sum[i]=sum[i-1]+dis(i-1,i);
        w[i] = w[i-1]+z;
        dist[i] = dis(0,i);
      }
      while(!Q.empty()) Q.pop_back();
      d[n] = 0;
      Q.push_back(n);
      for(int i=n-1;i>=0;i--){
         while(!Q.empty()&&w[Q.front()]-w[i]>c) Q.pop_front();
         d[i]=func(Q.front())+dist[i+1]-sum[i+1];
         while(!Q.empty()&&func(i)<=func(Q.back())) Q.pop_back();
         Q.push_back(i);
      }
      printf("%d\n",d[0]);
      if(T)printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值