首页 > 其他 > 详细

【JZOJ 1415】 单足跳

时间:2020-03-22 11:39:28      阅读:59      评论:0      收藏:0      [点我收藏+]

题目大意:

\(n\) 个方块,一开始在第一个方块,第一次只能跳到第二个方块上,接下来可以往前或往后跳。如果往前跳那跳跃距离必须比上一次要大 \(1\),如果往后跳那跳跃距离必须跟上一次一样。每跳到一个方块都要花费 \(a_i\) 代价,求从一跳到 \(n\) 的最小代价是多少。

正文:

明显可以使用动态规划解决这一问题,设 \(f_{i,j}\) 表示跳到第 \(i\) 个方块且跳跃距离是 \(j\) 时的最小代价。

因为有往后跳的因素,先枚举 \(i\) 再枚举 \(j\) 会产生关于后效性的问题,所以先枚举 \(j\) 再枚举 \(i\)。先考虑往后跳,毕竟跳跃距离一样,那目标就是 \(f_{i-j,j}\) 转移方程是:

\[f_{i-j,j}=\min\{f_{i,j}+a_{i-j}\}\]

因为如果往前跳那跳跃距离必须比上一次要大 \(1\),目标是 \(f_{i+j+1,j+1}\),动态转移方程是:

\[f_{i+j+1,j+1}=f_{i,j}+a_{i+j+1}\]

代码:

memset (f, 60, sizeof f);
scanf ("%d", &n);
for (int i = 1; i <= n; i++)
    scanf ("%d", &a[i]);
f[2][1] = a[2];
for (int j = 1; j <= n - 1; j++)
{
    for (int i = n; i >= j + 1; i--)
        f[i - j][j] = min(f[i - j][j], f[i][j] + a[i - j]);
    for (int i = 1; i <= n - j - 1; i++)
        if(f[i][j] != 1010580540)
            f[i + j + 1][j + 1] = f[i][j] + a[i + j + 1];
    ans = min(ans, f[n][j]);
}
printf("%d", ans);
return 0;

【JZOJ 1415】 单足跳

原文:https://www.cnblogs.com/GJY-JURUO/p/12543762.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!