UVA 1169 Robotruck

18 篇文章 0 订阅

dp[i] 表示从原点出发,将前i个垃圾处理的最小距离

dis[i] 表示从原点一直到第i个的总距离   所以  dis[i]-dis[j+1] 表示从第就j+1 到 i 的距离    odis[i] 表示第i个到原点的距离,w[i] 表示前i个的质量之和 

dp[i]=  min(dp[j]+odis[j+1]+dis[i]-dis[j+1]+odis[i] )     j<=i    w[i]-w[j]<=c

令cal( j) =  dp[j]-dis[j+1]+odis[j+1]  

单调队列q  维护的  是  cal(q[ ]) 单调递增

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
typedef long long lld;
typedef unsigned long long ull;
const int maxn = 100010;
int n,c;
int dp[maxn],w[maxn],dis[maxn],x[maxn],y[maxn],odis[maxn];
int q[maxn];
int f,r;
int cal(int i)
{
    return dp[i]-dis[i+1]+odis[i+1];
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d",&c,&n);
        dis[0]=0;w[0]=0;
        x[0]=0;y[0]=0;
        for(int i=1;i<=n;i++)
        {
            int z;
            scanf("%d %d %d",&x[i],&y[i],&z);
            dis[i]=dis[i-1]+abs(x[i]-x[i-1])+abs(y[i]-y[i-1]);
            w[i]=w[i-1]+z;
            odis[i]=x[i]+y[i];
        }
        f=r=1;
        q[1]=0;
        for(int i=1;i<=n;i++)
        {
            while(f<=r&&w[i]-w[q[f]]>c) f++;
            dp[i]=cal(q[f])+dis[i]+odis[i];
            while(f<=r&&cal(i)<=cal(q[r])) r--;
            q[++r]=i;
        }
        printf("%d\n",dp[n]);
        if(T>0) puts("");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值