题目链接:
题目大意:在X轴上有一个餐厅,以及有n个点要送外卖。餐厅坐标为x,工人的速度为V秒1米,。给出n的点的x坐标和参数v,外卖没送到,客户就会不愉快,每一分钟的不愉快指数增加v[i]。问怎么样的送货策略,使得所有客户的总不愉悦指数和最小。


思路:我们把n个要送的外卖点和店的位置进行排序。


i为店的位置,那么他下一次要么去i-1,或者i+1。

假如下一次去了i-1。接下来:

要么去i-2,或者i+1。

那么用dp[L][R][0/1]分别表示把区间[L, R]的人外卖送完,用的最小时间。

那么如图:

dp[L][R][0]只能由dp[L+1][R][0]或者dp[L+1][R][1]转移而来。
同理:dp[L][R][1]只能由dp[L][R-1][0]或者dp[L][R-1][1]转移而来。

L和R开始=店的起始位置,并且L只能–,R只能++。

还有我们要把这个dp[L][R][0]送餐过程,[1, L]和[R+1, n]等待是愤怒值加在dp[L][R][0]上。那么可以消除时间对无后效性的影响。这个性质在之前的博客也有体现。

#include <bits/stdc++.h>

#define LL long long
using namespace std;

struct node
{
    LL x;
    LL v;
}a[1005];

LL s[1005];
LL dp[1005][1005][2];
int cmp(node &a, node &b)
{
    return a.x<b.x;
}

LL sum(int L, int R)
{
    return s[R]-s[L-1];
}

LL dfs(int n, int p)
{
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
            dp[i][j][0]=dp[i][j][1]=1ll*10000000000;
    }

    int pos;
    for(int i=1;i<=n;i++)
    {
        if(a[i].x==p)
        {
            pos=i;
        }
    }
    dp[pos][pos][0]=dp[pos][pos][1]=0;
    for(int L=pos; L>=1; L--)
    {
        for(int R=pos; R<=n; R++)
        {
            if(L==R)
            {
                continue;
            }

            dp[L][R][0]=min(1ll*10000000000, dp[L+1][R][0]+abs(a[L+1].x-a[L].x)*(sum(1,L)+sum(R+1,n)));

            dp[L][R][0]=min(dp[L][R][0], dp[L+1][R][1]+abs(a[R].x-a[L].x)*(sum(1, L)+sum(R+1, n)));

            dp[L][R][1]=min(1ll*10000000000, dp[L][R-1][1]+abs(a[R].x-a[R-1].x)*(sum(1, L-1)+sum(R, n)));

            dp[L][R][1]=min(dp[L][R][1], dp[L][R-1][0]+abs(a[R].x-a[L].x)*(sum(1, L-1)+sum(R, n)));

        }
    }

    return min(dp[1][n][0], dp[1][n][1]);

}

int main()
{
    int n, v, p;
    while(~scanf("%d%d%d",&n,&v,&p))
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld",&a[i].x,&a[i].v);
        }
        a[n+1].x=p, a[n+1].v=0;
        sort(a+1, a+n+2, cmp);
        s[0]=0;
        for(int i=1;i<=n+1;i++)
        {
            s[i]=s[i-1]+a[i].v;
        }
        cout<<dfs(n+1, p)*v<<endl;
    }

    return 0;
}