I - Road Optimization(cf原题)题解

[题目传送门](Problem - 1625C - Codeforces (Unofficial mirror by Menci))

题目大意:

两地之间相隔长度为 l , 其中有 n 个限速标志,最多可以删除 k 个限速标, 第 i 个限速标志表示在离起点 di 公里的距离。求从起点到终点最少需要的时间。

 

 

答案就是删除 0 ~ k 个限速标到终点的最短时间,我们并不清楚我们什么时候需要删除限速标,也不知道每次需要删除多少。

我们设置一个 a 数组用来存储每个限速标所限制的速度,d 数组用来存储每一个限速标的位置。

我们可以开一个二维数组 f [ i ] [ j ] 表示到第 i 个限速标的时候删掉了 j 个限速标的最小花费时间。这里需要注意,我们第一个限速标是不能删掉的,因为那样我们就不知道第一段距离的速度了。

在第一个限速标所需要的时间为 0 ,所以我们需要将 f [ i ] [ j ] 中 i == 1时的数据初始化为 0 。

还有就是我们用来存储每个限速标位置的数组 d 还需要去存储一下我们最后的终点,可以把终点理解成一个没有限速标的节点。

明确了数组中所对应的元素,我们再来判断一下可能会遇到的情况:

1、从上一个限速标到目前的限速标,没有删除一个限速标 / 删除了 0 个限速标(此时 j 不会改变):

  f [ i ] [ j ] = f [ i - 1 ] [ j ] + ( d [ i ] - d [ i - 1 ] ) * a [ i  - 1 ]; //  d [ i ] - d [ i - 1 ] 表示上一个限速标的位置到目前的限速标的位置之间的距离,因为这一段的速度是上一个限速标的速度所以乘以 a [ i  - 1 ]

2、从上一个限速标到目前的限速标,删除了 m 个限速标:

  f [ i ] [ j ] = f [ i - 1 - m ] [ j  - m ] + ( d [ i ] - d [ i - 1 - m ] ) * a [ i  - 1 - m ]; // 好像删除了几个限速标就是把等号后面的变成前 n 个位置的元素。

这样看动规公式就应该是:

  f [ i ] [ j ] = min ( f [ i ] [ j ] , f [ i - 1 - m ] [ j - m ] + ( d [ i ] - d [ i - 1 - m ] ) * a [ i  - 1 - m ] );

** 因为第 1 个限速标不能被删除,所以在 i 个位置的时候不能删除多于 i - 1 个限速标,所以第 i 个位置能删除的最大限速标的数量应该为 min ( i - 1,  k );

 1 for (int i = 2; i <= n + 1; i++)//因为第 1 个限速标不能删我们可以不去考虑
 2     {
 3         for (int j = 0; j <= min(i - 1, k); j++)
 4         {
 5             for (int l = 0; l <= j; l++)
 6             {
 7                 f[i][j] = min(f[i][j], f[i - l - 1][j - l] + (d[i] - d[i - l - 1]) * a[i - l - 1]);
 8             }
 9         }
10     }

最后得到的 f [ n + 1] [ 0 ~ k ] 表示到达第 n + 1 个限速标也就是到了终点的时候删除了 0 ~ k 个限速标不同情况的最小时间,所以我们需要在其中找到最小值最为最后答案。

 

posted @ 2022-07-05 20:51  aYi_7  阅读(107)  评论(0)    收藏  举报