[BZOJ 1592] Making The Grade路面修整

2024-01-09 17:59

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

1592: [Usaco2008 Feb]Making the Grade 路面修整

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 704  Solved: 483
[Submit][Status][Discuss]

Description

FJ打算好好修一下农场中某条凹凸不平的土路。按奶牛们的要求,修好后的路面高度应当单调上升或单调下降,也就是说,高度上升与高度下降的路段不能同时出现在修好的路中。 整条路被分成了N段,N个整数A_1, ... , A_N (1 <= N <= 2,000)依次描述了每一段路的高度(0 <= A_i <= 1,000,000,000)。FJ希望找到一个恰好含N个元素的不上升或不下降序列B_1, ... , B_N,作为修过的路中每个路段的高度。由于将每一段路垫高或挖低一个单位的花费相同,修路的总支出可以表示为: |A_1 - B_1| + |A_2 - B_2| + ... + |A_N - B_N| 请你计算一下,FJ在这项工程上的最小支出是多少。FJ向你保证,这个支出不会超过2^31-1。

Input

* 第1行: 输入1个整数:N * 第2..N+1行: 第i+1行为1个整数:A_i

Output

* 第1行: 输出1个正整数,表示FJ把路修成高度不上升或高度不下降的最小花费

Sample Input

7
1
3
2
4
5
3
9

Sample Output

3

HINT

FJ将第一个高度为3的路段的高度减少为2,将第二个高度为3的路段的高度增加到5,总花费为|2-3|+|5-3| = 3,并且各路段的高度为一个不下降序列 1,2,2,4,5,5,9。

这题显然是个 $DP$ ...

首先我们可以设置记忆化数组 $f_{i,j}$ ,代表前 $i$ 步可以取得的最大高度为 $j$ .因为高度的范围比较大但是数据个数不多所以考虑离散化一发.

离散化之后 $DP$ 转移方程还算明确

\[ f_{i,j}=min( f_{i,j-1}, f_{i-1,j}+ \left | a_i - b_j \right | )\]

其中 $a_i$ 为第 $i$ 个路段的高度, $b_i$ 的意义是若某路段的高度在离散化后的结果为 $i$ ,则原数据为 $b_i$ .

然后由于题目要求可以单调不降或者单调不升, 所以应该扫描两遍然后取较小答案, 枚举 $j$ 时要一次正向一次反向.

然后参考代码如下:

GitHub

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <iostream>
 5 #include <algorithm>
 6 
 7 const int MAXN=2010;
 8 const int INF=0x3FFFFFFF;
 9 
10 int n;
11 int m;
12 int data[MAXN];
13 int hash[MAXN];
14 int dp[MAXN][MAXN];
15 
16 int Hash(int);
17 void Initialize();
18 int DynamicProgramming();
19 
20 int main(){
21     Initialize();
22     printf("%d\n",DynamicProgramming());
23     return 0;
24 }
25 
26 int DynamicProgramming(){
27     memset(dp,0x3F,sizeof(dp));
28     memset(dp[0],0,sizeof(dp[0]));
29     for(int i=1;i<=n;i++){
30         for(int j=1;j<=m;j++){
31             dp[i][j]=std::min(dp[i-1][j]+abs(hash[j]-data[i]),dp[i][j-1]);
32         }
33     }
34     int ans=dp[n][m];
35     memset(dp,0x3F,sizeof(dp));
36     memset(dp[0],0,sizeof(dp[0]));
37     for(int i=1;i<=n;i++){
38         for(int j=m;j>0;j--){
39             dp[i][j]=std::min(dp[i-1][j]+abs(hash[j]-data[i]),dp[i][j+1]);
40         }
41     }
42     ans=std::min(ans,dp[n][1]);
43     return ans;
44 }
45 
46 void Initialize(){
47     scanf("%d",&n);
48     for(int i=1;i<=n;i++){
49         scanf("%d",data+i);
50     }
51     memcpy(hash,data,sizeof(data));
52     std::sort(hash+1,hash+n+1);
53     m=std::unique(hash+1,hash+n+1)-(hash+1);
54 }
55 
56 inline int Hash(int x){
57     return std::lower_bound(hash+1,hash+m+1,x)-hash;
58 }
Backup

 

 

转载于:https://www.cnblogs.com/rvalue/p/7274821.html

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



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

相关文章

【POJ 3666】Making the Grade(简单DP)

首先可以明确一个方面,那就是如果将X改成Y,那么Y肯定是这N个数中的某一个(为什么仔细想想) 之后可以得到一个状态转移那就是dp[i][j]代表已经考虑了i位的情况下,结尾为j的最小更改数。 状态转移为dp[i][j] = min(dp[i-1][k] + abs(a[i] - b[j])) 这样的话可以写出一个初步的代码: #include<cstdio>#include<cst

[论文笔记]Making Large Language Models A Better Foundation For Dense Retrieval

引言 今天带来北京智源研究院(BAAI)团队带来的一篇关于如何微调LLM变成密集检索器的论文笔记——Making Large Language Models A Better Foundation For Dense Retrieval。 为了简单,下文中以翻译的口吻记录,比如替换"作者"为"我们"。 密集检索需要学习具有区分性的文本嵌入,以表示查询和文档之间的语义关系。考虑到大语言模

【BZOJ】1324 Exca王者之剑 最大权独立集

传送门:【BZOJ】1324  Exca王者之剑 题目分析:赤裸裸的最大权独立集。。。最小割解决 代码如下: #include <cstdio>#include <vector>#include <cstring>#include <algorithm>using namespace std ;#define REP( i , a , b ) for ( int

【BZOJ】1026: [SCOI2009]windy数 数位DP

传送门:【BZOJ】1026: [SCOI2009]windy数 题目分析:数位DP水题。 代码如下: #include <stdio.h>#include <cstring>#include <algorithm>#define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )#define For( i ,

【BZOJ】2152: 聪聪可可 点分治

传送门:【BZOJ】2152: 聪聪可可 题目分析:记录权值和%3的路径的个数。。。然后去重。。没了。。 代码如下: #include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std ;typedef lo

【ZOJ】3889 Making Sequence【构造】

传送门:【ZOJ】3889 Making Sequence 根据题意构造即可。ZOJ月赛我们抢的第二个FBwww my  code: my~~code: #include <bits/stdc++.h>using namespace std ;typedef unsigned long long ULL ;const int MAXN = 205 ;ULL n , a , b , s ,

基于yolov8的路面垃圾检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的路面垃圾检测系统是一种利用深度学习技术实现的高效、精准的路面垃圾检测解决方案。该系统采用了YOLOv8目标检测算法,该算法在速度和精度上均表现出色,能够实时或近实时地检测路面上的垃圾。 系统通过训练YOLOv8模型,使其能够识别并定位多种类型的路面垃圾,如塑料袋、纸屑等。在实际应用中,系统可以支持图片、视频以及摄像头的输入,通过界面实时显示目标位置、检测结果、和

BZOJ 2440 2301 莫比乌斯应用

http://www.lydsy.com/JudgeOnline/problem.php?id=2440 Description 小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些 数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而 这丝毫不影响他对其他数的热爱。  这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一 个小X讨厌

BZOJ 3732: Network(最小生成树+倍增)

题目链接 题意:给出一个图,每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少 很明显最终查询的边一定是在最小生成树里面的,先跑出最小生成树,然后,可以树链剖分,也可以使用倍增来计算 #include<bits/stdc++.h>using namespace std;#define cl(a,b) memset(a,b,sizeof(a))#define

build.grade.kts 如何定义插件及插件扩展

定义插件和应用插件 在build.gradle.kts文件内 这里要注意的是,最后一行的Project扩展函数名必须要和上面apply方法里面create的参数一致,然后project扩展函数定义之前必须先apply<>()也就是先使用apply让plugin apply方法运行起来,才能创建到这个snowmanExtension扩展函数,才能在下面进行定义。否则会报错。这样就可以在别的地方使用