LevOJ P1779 小胡同学的跳板
题目描述
小胡同学在出题的时候感到有点饿,于是决定出去找点吃的。
小胡同学住在一条长长的公路的一头。为了方便行动,小胡同学找小水同学沿路安装了一些跳板。每个跳板能够将胡同学发射到一定距离内的任意位置。
在公路的另一头,有小胡同学很喜欢吃的炸鸡店。小胡同学想请你帮忙计算,在充分利用跳板的情况下,他要走多远才能到达炸鸡店。
输入描述
第一行两个整数 N 和 M 表示跳板的个数和炸鸡店到小胡同学家的距离
后面 N 行,第 i 行包含两个整数 Pi 和Xi 表示第 i 个跳板安装在距离小胡同学家Pi 处,它能够发射的距离为 Xi
数据保证:
-
N≤10^5
-
N≤M
-
∀i<j,Pi<Pj
-
0≤Pi≤M≤10^9
-
0<Xi≤10^9
输出描述
一个整数,表示胡同学要步行的距离。
样例输入 - 1
3 9
0 3
2 3
3 6
样例输出 - 1
0
动态规划有三大要点:第一,记忆化,第二,从最优解推最优解,第三,将问题进行替换。
首先要定义出一个状态,该状态必须要是能够递推的,所以其次要找出该状态的状态转移方程。
在这个问题里,我们要怎么找到这个状态呢,
最终我们找到这个状态是第i个跳板能到达的最远距离,因为第i个距离能推出下一个跳板能到达的最远距离,具有连续性,并且当每个跳板能到达的最远距离都求出来时,我们
就能求出最终要走的距离。
要走的距离,有三部分组成,第一,起点到第一个跳板的距离,第二,最后一个跳板到终点的距离,第三,中间所有的跳板过渡时要走的距离。
第一,二很好理解,也很好算,重要的是第三个。
我们可以分以下几种情况讨论,第一种,第i个跳板的最大距离够不到第i+1个跳板,这时候要走的距离就是如图1所示
下一个跳板的最远距离也很容易算,就是它本身的距离加上能跳的距离
第二种,第i个跳板的最大距离能够到第i+1个跳板,这时要判断第i个跳板的最大距离和第i+1个跳板的最大距离谁远,如图2所示


这时候没有要走的距离
1 #include <iostream> 2 using namespace std; 3 #define N 100000 4 int main() 5 { 6 int n, m, dp[N], x[N], p[N]; 7 cin >> n >> m; 8 for (int i = 0; i < n; i++) 9 cin >> p[i] >> x[i]; 10 int s = 0; 11 if (p[0] > 0) 12 s = p[0]; 13 dp[0] = p[0] + x[0]; 14 for (int i = 0; i < n; i++) 15 { 16 if (dp[i] < p[i + 1]) //最大距离够不到下一个跳板 17 { 18 s += p[i + 1] - dp[i]; //行走距离增加 19 dp[i + 1] = p[i + 1] + x[i + 1]; 20 } 21 else 22 { 23 if (dp[i] < p[i + 1] + x[i + 1]) //最大距离没下一个能达到的最大距离远 24 dp[i + 1] = p[i + 1] + x[i + 1]; 25 else //比下一个能到的远 26 dp[i + 1] = dp[i]; 27 } 28 } 29 if (dp[n - 1] < m) 30 s += m - dp[n - 1]; 31 cout << s << endl; 32 }
把所有跳板遍历一遍即可得出答案。

浙公网安备 33010602011771号