zoj 3469 Food Delivery

//只需将起始点设为水平基准点LEV,即可DP算出答案

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAX 1002
struct Info{
    int coor,w;
}info[MAX];
int cmp(struct Info a,struct Info b)
{
    return a.coor<b.coor;
}
int dp[MAX][MAX][2];
int min(int a,int b)
{
    return (a<b)?a:b;
}
int main()
{
    int N,V,start,i,left,LEV,j,total,temp,LEFT;
   
    while(~scanf("%d%d%d",&N,&V,&start))
    {
        total=0;
        for(i=1;i<=N;i++)
        {
            scanf("%d%d",&info[i].coor,&info[i].w);
            total+=info[i].w;
        }
        sort(info+1,info+1+N,cmp);
        for(i=1;i<=N;i++)
        {
            if(info[i].coor<start)
                info[i-1]=info[i];
            else
            {
                info[i-1].coor=start;
                info[i-1].w=0;
                LEV=i-1;
                break;
            }
        }
    if(i>N)
        info[N].coor=start,info[N].w=0,LEV=N;
        LEFT=0;
        for(i=LEV;i>=0;i--)
        {
            LEFT+=info[i].w;
            left=LEFT;
            for(j=LEV;j<=N;j++)
            {
                left+=info[j].w;
                if((i==LEV)&&(j==LEV))
                    dp[i][j][0]=dp[i][j][1]=0;
                else
                {
                    if((i==LEV)||(j==LEV))
                    {
                        if(i==LEV)
                        {
                            dp[i][j][1]=dp[i][j-1][1]+(total-left+info[j].w)*(info[j].coor-info[j-1].coor);
                            dp[i][j][0]=dp[i][j][1]+(total-left)*(info[j].coor-info[LEV].coor);            
                        }
                        else
                        {
                            dp[i][j][0]=dp[i+1][j][0]+(total-left+info[i].w)*(info[i+1].coor-info[i].coor);
                            dp[i][j][1]=dp[i][j][0]+(total-left)*(info[LEV].coor-info[i].coor);        
                        }
                    }
                    else
                    {
                        temp=(total-left+info[i].w);
                        dp[i][j][0]=min(dp[i+1][j][0]+temp*(info[i+1].coor-info[i].coor),dp[i+1][j][1]+temp*(info[j].coor-info[i].coor));
                        temp=(total-left+info[j].w);
                        dp[i][j][1]=min(dp[i][j-1][1]+temp*(info[j].coor-info[j-1].coor),dp[i][j-1][0]+temp*(info[j].coor-info[i].coor));
                        
                    }
                }
            }
        }
        printf("%d\n",V*min(dp[0][N][0],dp[0][N][1]));
    }
    return 0;
}

posted @ 2012-05-25 16:21  SprintWater  阅读(129)  评论(0)    收藏  举报