LevOJ P1779 小胡同学的跳板

题目描述

小胡同学在出题的时候感到有点饿,于是决定出去找点吃的。

小胡同学住在一条长长的公路的一头。为了方便行动,小胡同学找小水同学沿路安装了一些跳板。每个跳板能够将胡同学发射到一定距离内的任意位置。

在公路的另一头,有小胡同学很喜欢吃的炸鸡店。小胡同学想请你帮忙计算,在充分利用跳板的情况下,他要走多远才能到达炸鸡店。

输入描述

第一行两个整数 N 和 M 表示跳板的个数和炸鸡店到小胡同学家的距离

后面 N 行,第 i 行包含两个整数 Pi 和Xi 表示第 i 个跳板安装在距离小胡同学家Pi 处,它能够发射的距离为 Xi

数据保证:

  • N10^5

  • NM

  • i<j,Pi<Pj

  • 0PiM10^9

  • 0<Xi10^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 }

 

把所有跳板遍历一遍即可得出答案。

 

 
posted @ 2022-04-20 10:44  海浩河  阅读(525)  评论(0)    收藏  举报