Making the Grade 路面修整

2024-01-09 17:59
文章标签 路面 grade making 修整

本文主要是介绍Making the Grade 路面修整,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

「POJ 3666」Making the Grade 路面修整

1 算法标签

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

2 题目难度

提高/提高+

3 题面

「POJ 3666」Making the Grade 路面修整

4 分析题面

4.1 简要描述

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

4.2 模型转换

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

5 问题分析

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

考虑已经选了 n n n个数

  • n = 1 n=1 n=1 A 1 = B 1 A_1=B_1 A1=B1 S S S最小为 ∣ A 1 − B 1 ∣ |A_1-B_1| A1B1

  • n > 1 n>1 n>1,前面已经选择了 n − 1 n-1 n1个数,取得了最小值,考虑怎么取第 n n n个数

    • A i ≥ B i − 1 A_i≥B_{i-1} AiBi1 B i = A i B_i=A_i Bi=Ai显然最优

    • A i < B i − 1 A_i<B_{i-1} Ai<Bi1

      • B i = A i B_i=A_i Bi=Ai

      • B k , B K + 1 , . . . , B i B_k,B_{K+1},...,B_i Bk,BK+1,...,Bi都赋值为 A k , A k + 1 , . . . , A i A_k,A_k+1,...,A_i Ak,Ak+1,...,Ai的中位数

        口胡证明:

        我们可以将 B k , B K + 1 , . . . , B i B_k,B_{K+1},...,B_i Bk,BK+1,...,Bi标记在数轴上,再将 A k , A k + 1 , . . . , A i A_k,A_k+1,...,A_i Ak,Ak+1,...,Ai标记上

        那么,其实 S S S的几何含义就是每一组 A i A_i Ai B i B_i Bi的距离之和

        我们也学过绝对值问题: ∣ x − k 1 ∣ + ∣ x − k 2 ∣ + ∣ x − k 3 ∣ . . . |x-k_1|+|x-k_2|+|x-k_3|... xk1+xk2+xk3...的最小值这种

        其实和这里的 S S S是没有任何区别的

        所以,我们知道零点分段法

        就是取中位数(就是使每个绝对值内部为0的x答案数组的中位数)

        可以使得绝对值之和最小

        1. 如果x在两个 k k k之间,那么无论x在哪,距离之和都是这两个k的距离
        2. 如果在这两个 k k k之外,那么距离之和则为两个k距离加上两倍的x距近的k的距离,肯定小于第一种情况

        那么我们只要尽量让 x x x在越多的 k k k之间即可

        那么最佳x在图中就是 4 4 4,如果 k k k的个数为偶数n,则是 k n / 2 k_{n/2} kn/2 K n / 2 + 1 K_{n/2+1} Kn/2+1之间

        综上,选择中位数最佳

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

但是!

我们可以得到一个结论:

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

所以,我们可以考虑dp

阶段:到第 i i i

状态: d p i , j dp_{i,j} dpi,j表示以 B j B_j Bj结尾的 S m i n S_{min} Smin

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

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

转移方程: d p i , j = m i n ( d p i − 1 , j ) + ∣ A i − B j ∣ , 其 中 1 ≤ j ≤ n dp_{i,j}=min(dp_{i-1,j})+|A_i-B_j|,其中1≤j≤n dpi,j=min(dpi1,j)+AiBj,1jn

6 实现细节

6.1 滚动数组

开二维数组有点浪费欸

那怎么办呢?

由于我们只用到了 i − 1 i-1 i1

所以,我们考虑用滚动数组优化,用位运算符&来记录,这样就只用了 0 / 1 0/1 0/1来表示,重复利用,节省空间

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

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

窝jio得这个还是很香的

i − > i i->i i>i & 1 1 1 i − 1 − > ( i − 1 ) i-1->(i-1) i1>(i1)& 1 1 1

方程就变成了这样:

d p [ i dp[i dp[i& 1 ] [ j ] = m i n ( d p [ ( i − 1 ) 1][j]=min(dp[(i-1) 1][j]=min(dp[(i1)& ] [ k ] ) + ∣ A [ i ] − B [ j ] ∣ , 其 中 1 ≤ j ≤ n , 1 ≤ k ≤ j ][k])+|A[i]-B[j]|,其中1≤j≤n,1≤k≤j ][k])+A[i]B[j],1jn,1kj

6.2 最小值

但是这个复杂度。。

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

n < = 2000 n<=2000 n<=2000 的时候就已经game over了,显然不行啊

这个问题应该有手就行

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

(因为 k k k只到 j j j

6.3 降序

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

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

7 代码实现(增加代码注释)

#include<bits/stdc++.h>
using namespace std;
const int N=2e4+2;
int n,f[2][N],a[N],b[N],ans=0x3f3f3f3f;
bool cmp1(int x,int y){return x<y;
}//升序 
bool cmp2(int x,int y){return x>y;
}//降序 
void work(){for(int i=1;i<=n;i++){f[1][i]=abs(a[1]-b[i]);}//边界条件for(int i=2;i<=n;i++){int minn=f[(i-1)&1][1];for(int j=1;j<=n;j++){minn=min(minn,f[(i-1)&1][j]);//边更新边求f[i&1][j]=minn+abs(a[i]-b[j]);//滚动数组 }} for(int i=1;i<=n;i++){ans=min(ans,f[n&1][i]);}//求答案
}
int main(){scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);b[i]=a[i];//拷贝到b数组}sort(b+1,b+1+n,cmp1);//从小到大 work(); //dp计算sort(b+1,b+1+n,cmp2);//从大到小 work();//直接就是一样的啊printf("%d",ans);//输出最小return 0;
}

8 总结

  1. 最大的收获:dp!!!

  2. 新鲜的知识:更优秀的滚动数组写法

  3. 相似的题目:CF #371 div.1 C Sonya and Problem Wihtout a Legend

这篇关于Making the Grade 路面修整的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/587960

相关文章

开发一个python工具,pdf转图片,并且截成单个图片,然后修整没用的白边及循环遍历文件夹全量压缩图片

§ 今天推荐一键款本人开发的pdf转单张图片并截取没有用的白边工具 § 一、开发背景: 业务需要将一个pdf文件展示在前端显示,但是基于各种原因,放弃了h5使用插件展示 原因有多个,文件资源太大加载太慢、pdf展示兼容性问题、pdf展示效果不好、pdf字体有时缺失等等,所以将项目中的协议等,全部由pdf文档转成图片,因为文档太多,不可能找UI同学一个一个截图,所以我就基于python代码写了三

开发一个python工具,pdf转图片,并且截成单个图片,然后修整没用的白边

今天推荐一键款本人开发的pdf转单张图片并截取没有用的白边工具 一、开发背景: 业务需要将一个pdf文件展示在前端显示,但是基于各种原因,放弃了h5使用插件展示 原因有多个,文件资源太大加载太慢、pdf展示兼容性问题、pdf展示效果不好、pdf字体有时缺失等等,所以将项目中的协议等,全部由pdf文档转成图片,因为文档太多,不可能找UI同学一个一个截图,所以我就基于python代码写了三个工具。

英语学习笔记37——Making a bookcase

Making a bookcase 做书架 词汇 Vocabulary work v. 工作 ing形式:working 搭配:work on + 工作 做……工作    work for + 人 为……而工作 例句:我正在做我的家庭作业。    I am working on my homework.    我正在为Bobby工作。    I am working for Bobby. n.

hdu 5038 Grade

hdu 5038 Grade 给定一个计算公示 以及W的值 计算会出现多少种结果  主要是  输入n=1的时候 直接输出结果而不是BAD #include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <string.h>#include <stri

操作系统论文导读(二十):Making Powerful Enemies on NVIDIA GPUs

RTSS-2022: Making Powerful Enemies on NVIDIA GPUs 目录 一、文章核心 二、文章背景 背景介绍 干扰通道 研究问题 文章的创新点 方法论 三、必要知识与相关工作 A 背景知识 CUDA 基础 GPU 硬件 并发和干扰通道 干扰通道 SM 内部干扰通道 B 相关工作 CPU时间分析 GPU时间分析 GPU共享 四

Android studio 多渠道(多环境)打包grade配置详解

Android studio 多渠道(多环境)打包grade配置详解 场景:开发app,我们需要两套环境或者两套环境以上的apk,每套环境的apk分两个版本debug版和release版。 公司有套平时开发测试的接口地址:http ://alpha.xx 上线发布的时候接口对应地址:http://produce.xx 问题:我们如何通过配置这两个地址,每次自动打出两个环境的apk而不需要修

openlayers官方教程(十)Vector Data——Making it look nice

Making it look nice 前面已经完成了基础的功能,包括导入、编辑、导出。但是没有做一下美化,当你创建了一个矢量图层,会默认很多样式。编辑过程中的交互也是默认的样式,你可能注意到在编辑过程中线条很粗,这个可以通过向矢量图层和交互提供style来控制这些属性。 Static style 如果我们给所有要素集定义通用的样式,可以如下配置: const layer = ne

Hdu 5038 Grade(2014 ACM/ICPC Asia Regional Beijing Online 1007)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5038 题目的意思, 给你公式,求出每个蘑菇的grade,求这些grade的众数。。Mode,众数,表示英语又被鄙视了。 表示,自己很弱,不知道众数的定义。。。 百度之。。。 一般来说,一组数据中,出现次数最多的数就叫这组数据的众数。 例如:1,2,3,3,4的众数是3。

计算机视觉与深度学习实战,Python工具,路面裂缝检测系统设计

一、引言 随着城市交通的日益繁忙,路面的损耗和破损问题也日益凸显。路面裂缝是道路破损的常见形式,及时发现并处理这些裂缝对于保障交通安全、延长道路使用寿命具有重要意义。传统的路面裂缝检测方法主要依赖人工巡检,但这种方法效率低下且易受人为因素影响。近年来,随着计算机视觉和深度学习技术的快速发展,基于图像识别的自动化路面裂缝检测系统逐渐成为研究热点。本文将以Python为工具,探讨如何设计一个路面

android studio管理grade

把老的代码拷贝到新的本本上,发现grade版本错了。报错 could not find com.android.tools.buildgradle 打开log,找到android目录,发现我的系统是2.0.0,工程配置是2.3 直接修改工程配置。搞定。