zoukankan      html  css  js  c++  java
  • zoj 3031 Robotruck(dp + 单调队列)

    题意:有n个垃圾,机器人要按照编号从小到大捡但手中的垃圾不得超过C,求出机器人行走的最短总路程。

    做法:设dp[i]为捡第i个垃圾的最短距离,dist[i]为按顺序的总长,dis_ori[i]为i到原点的距离。

    不难得出:dp[i] = min{dp[j] + dis_ori[j+1] + distance[j+1,i] + dis_ori[i] }  ;         w(j+1,i)<=C

            = min{dp[j] + dis_ori[j+1] - dist[j+1]} + dist[i] + dis_ori[i] ;        w(j+1,i)<=C

    用单调队列可以解决min的值,复杂度O(n) , 注意long long。

    单调队列(窗口滑动技术):

    对于每一个状态f(x)来说,计算过程分为以下几步:

      1、 队首元素出队,直到队首元素在给定的范围中。

      2、 此时,队首元素就是状态f(x)的最优决策。

      3、 计算g(x),并将其插入到单调队列的尾部,同时维持队列的单调性(不断地出队,直到队列单调为止)。

    View Code
     1 /*
     2 Author:Zhaofa Fang
     3 Lang:C++
     4 */
     5 #include <cstdio>
     6 #include <cstdlib>
     7 #include <sstream>
     8 #include <iostream>
     9 #include <cmath>
    10 #include <cstring>
    11 #include <algorithm>
    12 #include <string>
    13 #include <utility>
    14 #include <vector>
    15 #include <queue>
    16 #include <stack>
    17 #include <map>
    18 #include <set>
    19 using namespace std;
    20 
    21 typedef long long ll;
    22 #define DEBUG(X) cout<< #X << ':' << X << endl
    23 #define REP(i,n) for(int i=0;i < (n);i++)
    24 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
    25 #define PII pair<int,int>
    26 #define PB push_back
    27 #define MP make_pair
    28 #define ft first
    29 #define sd second
    30 #define lowbit(X) (X&(-X))
    31 #define INF (1<<30)
    32 
    33 
    34 const int maxn = 1e5+10;
    35 ll dp[maxn],w[maxn],dist[maxn],dis_ori[maxn];
    36 int X[maxn],Y[maxn];
    37 int q[maxn];
    38 ll fun(int j)
    39 {
    40     return dp[j] + dis_ori[j+1] - dist[j+1];
    41 }
    42 inline int Abs(int k)
    43 {
    44     return k>0?k:(-k);
    45 }
    46 int main()
    47 {
    48     //freopen("in","r",stdin);
    49     int T;
    50     scanf("%d",&T);
    51     FOR(cas,1,T)
    52     {
    53         int C,n;
    54         scanf("%d%d",&C,&n);
    55         dp[0] = dist[0] = dis_ori[0] = w[0] = X[0] = Y[0] = 0;
    56         FOR(i,1,n)
    57         {
    58             scanf("%d%d%lld",&X[i],&Y[i],&w[i]);
    59             w[i] += w[i-1];
    60             dist[i] = dist[i-1] + Abs(X[i]-X[i-1]) + Abs(Y[i]-Y[i-1]);
    61             dis_ori[i] = Abs(X[i]) + Abs(Y[i]);
    62         }
    63         int front=0,rear=0;
    64         q[rear++] = 0;
    65         FOR(i,1,n)
    66         {
    67 
    68             while(front < rear && w[i] - w[q[front]] > C)front++;
    69             dp[i] = fun(q[front]) + dist[i] + dis_ori[i];
    70             while(front < rear && fun(q[rear-1]) >= fun(i))rear--;
    71             q[rear++] = i;
    72         }
    73         printf("%lld\n",dp[n]);
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    Jmeter如何保持cookie,让所有请求都能用同一个cookie,免去提取JSESSIONID
    Jmeter如何提取响应头部的JSESSIONID
    Loadrunner如何进行有效的IP欺骗
    Center 6.5 redis 3.0安装
    小程序 wx.getRecorderManager 录音 to 语音识别
    微信小程序语音识别服务搭建全过程解析(https api开放,支持新接口mp3录音、老接口silk录音)
    java自然语言理解demo,源码分享(基于欧拉蜜)
    微信小程序——智能小秘“遥知之”源码分享(语义理解基于olami)
    bash, sh, dash 傻傻分不清楚
    微信小程序语音识别服务搭建全过程解析(项目开源在github)
  • 原文地址:https://www.cnblogs.com/fzf123/p/2775697.html
Copyright © 2011-2022 走看看