其他分享
首页 > 其他分享> > 「POJ 3666」Making the Grade 路面修整 题解报告

「POJ 3666」Making the Grade 路面修整 题解报告

作者:互联网

「POJ 3666」Making the Grade 路面修整

个人评价(一句话描述对这个题的情感)

灰常好!( ̄▽ ̄)"

1 算法标签

dp动态规划+滚动数组优化

2 题目难度

提高/提高+

CF rating:2300

3 题面

「POJ 3666」Making the Grade 路面修整

4 分析题面

4.1 简要描述

给出数列 \(A\), 求非严格单调不上升或单调不下降, 且\(S=\sum^N_{i=1}|A_i-B_i|\) 最小的序列\(B\),输出\(S\)

4.2 模型转换

输入\(N\), 然后输入\(N\)个数,求最小的改动这些数使之成非严格递增或非严格递减即可

5 问题分析

以B为非严格单调递增为例

5.0 暴力

我们直接当考虑已经选了\(n\)个数:

5.1 dp(动态规划)

通过综上分析(5.0中),我们直接暴力模拟肯定是不行的(这个复杂度直接爆掉了)

但是!

我们可以从中得到一个\(very\) \(important\)的结论:

\(B\)数列中的每个数必定都为\(A\)数列中的元素

所以,我们可以考虑用\(dp\)来解决:

阶段:到第\(i\)位

状态:\(dp_{i,j}\)表示以\(B_j\)结尾的\(S_{min}\)

B数组是A的复制排序处理过后的数组

$\space \space $ \(dp[i][j]\)表示把前i个数变成不严格单调递增且第\(i\)个数变成原来第\(j\)大的数的最小代价

转移方程:\(dp_{i,j}=min(dp_{i-1,k})+|A_i-B_j|,其中1≤j≤n,1≤k≤j\)

6 实现细节

6.1 dp(动态规划)

6.1.1 滚动数组

从我们的\(dp\)方程:\(dp_{i,j}=min(dp_{i-1,k})+|A_i-B_j|,其中1≤j≤n,1≤k≤j\)

灰常容易地阔以算出空间复杂度是\(O(n^2)\)

这个。。秉承着我们能省则省的原则

看到这个开二维数组\(O(n^2)\)的空间貌似有点浪费

那怎么去优化空间呢?

又由于我们的\(dp\)方程中只用到了\(i-1\)的信息

于是我们下意识地反应:

——用滚动数组优化!

\(\space \space\)用位运算符&来记录,这样就只用了\(0/1\)来表示

重复利用,节省空间

\(\space\space\space\space\) \(i\)&\(1\)的效果和\(i\)%\(2\)的效果是一样的,但是\(i\)&\(1\)要快一点

\(\space\space\space\space\) 且这种方式比直接写\(0/1\)少了一个不断交换的过程

\(\space\space\space\space\) 窝jio得这个东西还是很·····香的

将\(i->i\) & \(1\),\(i-1->(i-1)\)&\(1\)

方程就变成了这样:

\(dp[i\)&\(1][j]=min(dp[(i-1)\)&\(][k])+|A[i]-B[j]|,其中1≤j≤n,1≤k≤j\)

6.1.2 最小值

但是这个复杂度。。

看上去好像是3层循环,就是\(O(n^3)\)啊

在\(n<=2000\) 的时候就已经\(game\space over\)了,显然不行啊

这个xiao问题应该有手就行

其实只要一边更新\(min(f[i-1][k])\)一般算当前的\(f[i][j]\)就行

(因为\(k\)只到\(j\))

6.1.3 降序

不严格单调不上升的情况也一样

更加方便的是可以把\(B\)数组从大到小排序后,做单调不下降的dp就

标签:...,3666,6.1,space,Grade,题解,个数,数组,dp
来源: https://www.cnblogs.com/Aurora1217/p/16347584.html