Zoj 3469 Food Delivery (DP

来源:互联网 发布:openwrt修改wan口mac 编辑:程序博客网 时间:2024/06/05 14:09

先把起始位置放到x坐标里面。然后从起始位置开始向左右送餐.

设dp[i][j][k]表示从第i个人到第j个人都已经送完餐最后停在 k== 0 在左边,k == 1 在右边的最不满值。

dp[i][j][0] 可能从dp[i+1][j][0],dp[i+1][j][1]  (i+1在i右边,两个都在i左边)转移而来,dp[i][j][1]可能从dp[i][j-1][0],dp[i][j-1][1]转移而来。具体状态转移方程参见代码。

   然后特别要注意的是每转移一次,都会增加一定的时间,后面的人拿到餐的时间也晚了,也就是说必须把对后面的影响考虑在当前状态下,并且对后面的每个人影响都是一样的,那么当前转移用时t,后面还有x(i-j区间之外)人,当前的状态就要多加 x * t,


/* * Author: fisty * Created Time: 2015/6/8 20:47:32 * File Name   : zoj3469.cpp *********************************************** */#include <iostream>#include <cstring>#include <deque>#include <cmath>#include <queue>#include <stack>#include <list>#include <map>#include <set>#include <string>#include <vector>#include <cstdio>#include <bitset>#include <algorithm>using namespace std;#define Debug(x) cout << #x << " " << x <<endl#define Memset(x, a) memset(x, a, sizeof(x))const int INF = 0x3f3f3f3f;typedef long long LL;typedef pair<int, int> P;#define FOR(i, a, b) for(int i = a;i < b; i++)#define MAX_N 1100int n, v, x;int sum[MAX_N];struct node{    int x;    int b;}a[MAX_N];bool cmp(node e1, node e2){    return e1.x < e2.x;}   int dp[MAX_N][MAX_N][2];void solve_sum(){    Memset(sum, 0);    for(int i = 1;i <= n; i++){        sum[i] = sum[i-1] + a[i].b;    }}   int main() {    //freopen("in.cpp", "r", stdin);    cin.tie(0);    ios::sync_with_stdio(false);    while(cin >> n >> v >> x){        Memset(a, 0);        FOR(i, 1, n+1) cin >> a[i].x >> a[i].b;        n++;        a[n].x = x, a[n].b = 0;        sort(a + 1, a + n + 1, cmp);//        for(int i = 0;i < n; i++){//            cout << a[i].x << " " << a[i].b << endl;//        }        solve_sum();        int p;        for(int i = 1;i <= n; i++){            if(a[i].x == x){                p = i;                break;            }        }        FOR(i, 1, n+1){            FOR(j, 1, n+1){                dp[i][j][0] = dp[i][j][1] = INF;            }        }        dp[p][p][0] = dp[p][p][1] = 0;        for(int i = p;i >= 1; i--){            for(int j = p;j <= n; j++){                if(i == j) continue;                dp[i][j][0] = min(dp[i][j][0], dp[i+1][j][0] + (sum[i] + sum[n] - sum[j]) * (a[i+1].x - a[i].x));                dp[i][j][0] = min(dp[i][j][0], dp[i+1][j][1] + (sum[i] + sum[n] - sum[j]) * (a[j].x - a[i].x));                dp[i][j][1] = min(dp[i][j][1], dp[i][j-1][0] + (sum[i-1] + sum[n] - sum[j-1]) * (a[j].x - a[i].x));                dp[i][j][1] = min(dp[i][j][1], dp[i][j-1][1] + (sum[i-1] + sum[n] - sum[j-1]) * (a[j].x - a[j-1].x));            }        }        cout << v*min(dp[1][n][0], dp[1][n][1]) << endl;    }    return 0;}


0 0
原创粉丝点击