Zoj 3469 Food Delivery (区间DP)

题目链接:

  Zoj 3469 Food Delivery

题目描述:

  在x轴上有n个客人叫外卖,每个顾客因为追的番更新进度不同,所以在等外买的时间里每秒增加的愤怒值不同。给出客人和餐厅的位置,以及客人每分钟增加的愤怒值,还有快递小哥的行走一公里需要的时间。问送完外卖后n个客人的最小愤怒值?

解题思路:

  区间DP,大一的时候做省赛练习的时候见过这种类型的题目,但是今天遇到由于年代久远,还是GG······。
  把餐厅所在的点加进去,然后按照在x轴上的位置排序。从餐厅所在位置向左右开始DP,dp[x][y][z] 代表 处理完区间[y, z]停留在x方向的最小花费,这个题目要预处理未加进去点的花费。然后选取最优。

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 typedef long long LL;
 8 const int INF = 0x3f3f3f3f;
 9 const int maxn = 1010;
10 struct node
11 {
12     int x, b;
13 } p[maxn];
14 LL dp[2][maxn][maxn], sum[maxn];//dp[0][x][y]左边 区间[x, y], dp[1][x][y]右边 区间[x, y]
15 
16 bool cmp (node a, node b)
17 {
18     return a.x < b.x;
19 }
20 
21 int main ()
22 {
23     int n, v, x;
24     while (scanf ("%d %d %d", &n, &v, &x) != EOF)
25     {
26         for (int i=1; i<=n; i++)
27             scanf ("%d %d", &p[i].x, &p[i].b);
28         p[++n].x = x;
29         p[n].b = 0;
30         sort (p+1, p+n+1, cmp);
31 
32         for (int i=0; i<=n; i++)
33             for (int j=0; j<=n; j++)
34                 dp[0][i][j] = dp[1][i][j] = INF;
35         int tem = 0;
36         for (int i=1; i<=n; i++)
37             if (p[i].x == x)
38             {
39                 tem = i;
40                 break;
41             }
42         dp[0][tem][tem] = dp[1][tem][tem] = 0;
43 
44         sum[0] = 0;
45         for (int i=1; i<=n; i++)
46             sum[i] = sum[i-1] + p[i].b;
47 
48 
49         for (int i=tem; i>0; i--)
50             for (int j=tem; j<=n; j++)
51             {
52                 if (i == j) continue;
53                 dp[0][i][j] = min (dp[0][i][j], dp[0][i+1][j]+(sum[n]-sum[j]+sum[i])*(p[i+1].x - p[i].x));
54                 dp[0][i][j] = min (dp[0][i][j], dp[1][i+1][j]+(sum[n]-sum[j]+sum[i])*(p[j].x - p[i].x));
55 
56                 dp[1][i][j] = min (dp[1][i][j], dp[1][i][j-1]+(sum[n]-sum[j-1]+sum[i-1])*(p[j].x - p[j-1].x));
57                 dp[1][i][j] = min (dp[1][i][j], dp[0][i][j-1]+(sum[n]-sum[j-1]+sum[i-1])*(p[j].x - p[i].x));
58             }
59         printf ("%lld\n", v * min (dp[0][1][n], dp[1][1][n]));
60     }
61     return 0;
62 }

 

posted @ 2015-11-03 18:25  罗茜  阅读(495)  评论(0编辑  收藏  举报