1 条题解
-
0
先看范围,我们只能采用 的时间复杂度。我们先要对整个序列进行排序,接下来我们要 DP。
我们对 的定义为:前面 个河狸移动的最优解。
动态规划过程
- 考虑前 个河狸已经分完, 两个分一组:最优解为其中一个河狸移动到另一个河狸的位置,距离为 ,则 可以从 递推。
- 考虑前 个河狸已经分完, 三个分一组:最优解为左右移动到中间河狸的位置,距离为 ,即 ,则 可以从 递推。
状态转移方程:$dp_i = \min(dp_{i-2} + a_i - a_{i-1}, dp_{i-3} + a_i - a_{i-2})$,请注意,此时的 应大于 ! 要大于 状态转移方程才成立,那么肯定有一个边界的问题。以下是状态转移方程的边界:
$\left\{\begin{matrix} dp_0&\gets& 0 &\text{没有河狸,不用移动}\\ dp_1&\gets& +∞ & \text{无解,设一个无穷大}\\ dp_2&\gets& a_2-a_1 &\text{两个河狸一组的情况}\\ dp_3&\gets& a_3-a_1 &\text{三个河狸一组的情况} \end{matrix}\right.$珍藏代码
#include<iostream> #include<algorithm> using namespace std; long long a[int(3e5+5)],dp[int(3e5+5)]; int main(){ int n; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } sort(a+1,a+n+1); dp[0]=0; dp[1]=1e18; dp[2]=a[2]-a[1]; dp[3]=a[3]-a[1]; for(int i=4;i<=n;i++){ dp[i]=min(dp[i-2]+a[i]-a[i-1],dp[i-3]-a[i-2]+a[i]); } cout<<dp[n]<<'\n'; return 0; }
最后说一句我的观点:我之所以用
long long
,是因为范围达到了 ,加来加去有可能超过 (int
类型的最大边界),所以开个long long
保平安。
信息
- ID
- 35575
- 时间
- 2000ms
- 内存
- 1024MiB
- 难度
- 3
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者