Food Delivery (ZOJ-3469, section DP)

1. Title link:

ZOJ-3469

2. The main idea of ​​the topic:

There are n customers on the number line, and there is a takeaway at point x. It takes v seconds for the takeaway to walk one meter. The anger value of customer i increases by b[i]

Find the minimum value of the sum of n customer anger values ​​after delivering n customers’ takeout.

3. Analysis:

The DP status of this question is very interesting. dp[i][j][0/1] means that after the delivery interval [i, j], and the delivery person is at point i/j, the minimum sum of n customer anger values .

In other words, the dp state is not the attribute of the interval state represented by the current subinterval, but the total set cost of the total set to reach the current state. (Ghost knows what I am talking about

4. Code implementation:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int M = (int)1e3;
const int inf = 0x3f3f3f3f3f3f3f3f;

struct node
{
    int x, b;
}s[M + 5];

ll dp[M + 5][M + 5][2];
ll sum[M + 5];

bool cmp(node a, node b)
{
    return a.x < b.x;
}

int main()
{
    int n, v, x;
    while(~scanf("%d %d %d", &n, &v, &x))
    {
        for(int i = 1; i <= n; ++i)
            scanf("%d %d", &s[i].x, &s[i].b);
        s[++n].x = x, s[n].b = 0;
        sort(s + 1, s + n + 1, cmp);
        for(int i = 1; i <= n; ++i)
            sum[i] = sum[i - 1] + s[i].b;
        int start = 0;
        while(s[++start].x != x);
        memset(dp, inf, sizeof(dp));
        dp[start][start][0] = dp[start][start][1] = 0;
        for(int i = start; i >= 1; --i)
        {
            for(int j = start; j <= n; ++j)
            {
                dp[i][j][0] = min(dp[i][j][0], dp[i + 1][j][0] + (s[i + 1].x - s[i].x) * (sum[n] - (sum[j] - sum[i])));
                dp[i][j][0] = min(dp[i][j][0], dp[i + 1][j][1] + (s[j].x - s[i].x) * (sum[n] - (sum[j] - sum[i])));
                dp[i][j][1] = min(dp[i][j][1], dp[i][j - 1][0] + (s[j].x - s[i].x) * (sum[n] - (sum[j - 1] - sum[i - 1])));
                dp[i][j][1] = min(dp[i][j][1], dp[i][j - 1][1] + (s[j].x - s[j - 1].x) * (sum[n] - (sum[j - 1] - sum[i - 1])));
            }
        }
        printf("%lld\n", min(dp[1][n][0], dp[1][n][1]) * v);
    }
    return 0;
}

 

Guess you like

Origin blog.csdn.net/The___Flash/article/details/104544230