Fork me on GitHub

2014 Super Training #2 C Robotruck --单调队列优化DP

原题: UVA 1169  http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3610

大白书上的原题。

 

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 100007

int dp[N],T[N];
int dis[N],wt[N];
int que[N];

struct Point
{
    int x,y,w;
}p[N];

int f(int j)
{
    return dp[j]-T[j+1]+dis[j+1];
}

int DIS(int i,int j)
{
    return abs(p[i].x-p[j].x) + abs(p[i].y-p[j].y);
}

int main()
{
    int t,C,n,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&C);
        scanf("%d",&n);
        memset(que,0,sizeof(que));
        wt[0] = 0;
        T[0] = 0;
        p[0].x = p[0].y = p[0].w = 0;
        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].w);
            wt[i] = wt[i-1] + p[i].w;
            T[i] = T[i-1] + DIS(i,i-1);
            dis[i] = DIS(i,0);
        }
        int head = 0;
        int tail = 0;
        for(i=1;i<=n;i++)
        {
            while(head <= tail && wt[i]-wt[que[head]] > C)
                head++;
            dp[i] = f(que[head]) + T[i] + dis[i];
            int fi = f(i);
            while(head <= tail && fi <= f(que[tail]))
                tail--;
            que[++tail] = i;
        }
        printf("%d\n",dp[n]);
        if(t)
            puts("");
    }
    return 0;
}
View Code

 

posted @ 2014-06-29 16:56  whatbeg  阅读(190)  评论(0编辑  收藏  举报