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;
}

浙公网安备 33010602011771号