题目描述:
在x轴上有n个客人叫外卖,每个顾客因为追的番更新进度不同,所以在等外买的时间里每秒增加的愤怒值不同。给出客人和餐厅的位置,以及客人每分钟增加的愤怒值,还有快递小哥的行走一公里需要的时间。问送完外卖后n个客人的最小愤怒值?
解题思路:
把餐厅所在的点加进去,然后按照在x轴上的位置排序。从餐厅所在位置向左右开始DP
dp[i][j][0]表示从i到j用户送到最小不开心值,此时送货员停留在左边即i位置
dp[i][j][1]表示从i到j用户送到最小不开心值,此时送货员停留在右边即j位置
状态有四种,
dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][0] + (a[i+1].x-a[i].x)*(sum[n]-sum[j]+sum[i]));
dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][1] + (a[j].x-a[i].x)*(sum[n]-sum[j]+sum[i]));
dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][0] + (a[j].x-a[i].x)*(sum[n]-sum[j-1]+sum[i-1]));
dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][1] + (a[j].x-a[j-1].x)*(sum[n]-sum[j-1]+sum[i-1]));
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <stack>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-3
#define maxn 100010
#define MOD 1000000007
struct node
{
int x,v;
bool operator < (const node &a)const
{
return x < a.x;
}
}a[1010];
int n,v,x;
int dp[1010][1010][2];
int sum[1010];
int main()
{
int t,C = 1;
while(scanf("%d%d%d",&n,&v,&x) != EOF)
{
memset(dp,INF,sizeof(dp));
for(int i = 1; i <= n; i++)
scanf("%d%d",&a[i].x,&a[i].v);
a[++n].x = x;
a[n].v = 0;
sort(a+1,a+n+1);
sum[0] = 0;
for(int i = 1; i <= n; i++)
sum[i] = sum[i-1] + a[i].v;
int tmp = 0;
for(int i = 1; i <= n; i++)
if(a[i].x == x)
tmp = i;
dp[tmp][tmp][0] = dp[tmp][tmp][1] = 0;
for(int i = tmp; i > 0; i--)
for(int j = tmp; j <= n; j++)
{
if(i == j)
continue;
dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][0] + (a[i+1].x-a[i].x)*(sum[n]-sum[j]+sum[i]));
dp[i][j][0] = min(dp[i][j][0],dp[i+1][j][1] + (a[j].x-a[i].x)*(sum[n]-sum[j]+sum[i]));
dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][0] + (a[j].x-a[i].x)*(sum[n]-sum[j-1]+sum[i-1]));
dp[i][j][1] = min(dp[i][j][1],dp[i][j-1][1] + (a[j].x-a[j-1].x)*(sum[n]-sum[j-1]+sum[i-1]));
}
printf("%d\n",v*min(dp[1][n][0],dp[1][n][1]));
}
return 0;
}