Making the Grade G

题意:

一个农夫需要修路,每一段路的海拔为 A i A_i Ai​,修改后的海拔为 B i B_i Bi​,花费为 ∣ A i − B i ∣ |A_i-B_i| ∣Ai​−Bi​∣,现在农夫想把 A 1 , A 2 . . . . . A n A_1,A_2.....A_n A1​,A2​.....An​的海拔改成单调的,问最少花费多少?

思路:

此题需要先推导一个结论,就是修改完后的序列里的每个数 B i B_i Bi​一定是原序列 A A A中已经存在过的。
以把序列改成非严格单调递增的为例,来证明。
改成非严格单调递减序列也是同样的证法。
证明:(数学归纳法)
n = 1 n=1 n=1,一定成立
对于 n = k − 1 n=k-1 n=k−1,假设一定成立
对于 n = k n=k n=k,此时如果 A n ≥ B n − 1 A_n≥B_{n-1} An​≥Bn−1​,那么显然 B n B_n Bn​用 A n A_n An​花费为0,结论成立。
此时如果 A n < B n − 1 A_n<B_{n-1} An​<Bn−1​,那么显然 B n B_n Bn​有两种选择
选择一要么是继续沿用 B n − 1 B_{n-1} Bn−1​
选择二要么是把当前的 B n B_n Bn​下调为 x x x,并且前面构造好的 B i B_i Bi​都要下调,把 B 1 , B 2 . . . B n − 1 B_1,B_2...B_{n-1} B1​,B2​...Bn−1​都要变成 x x x最小,如果前面这些数改成比 x x x更小的数,花费更小的话,那么在 k = n − 1 k=n-1 k=n−1时,就会执行,而不是等到 k = n k=n k=n时,所以此时就是选择一个 x x x使得 ∣ x − A 1 ∣ + ∣ x − A 2 ∣ + . . . . . + ∣ x − A n ∣ |x-A_1|+|x-A_2|+.....+|x-A_n| ∣x−A1​∣+∣x−A2​∣+.....+∣x−An​∣价值最小,众所周知,这是绝对值函数取最小值, x x x取这个序列的中位数即可,所以结论成立。
在知道结论的情况下,就可以定义状态方程 f ( i , j ) f(i,j) f(i,j)序列 A 1 . . . . A i A_1....A_i A1​....Ai​为止,第 i i i个数 B i B_i Bi​选择的时升序(降序)排序后序列里的第 j j j个数
所以此时 f ( i , j ) = m i n ( f ( i − 1 , k ) + ∣ A i − B k ∣ ) f(i,j)=min(f(i-1,k)+|A_i-B_k|) f(i,j)=min(f(i−1,k)+∣Ai​−Bk​∣) ( 1 ≤ k ≤ j ) (1≤k≤j) (1≤k≤j),里面的 f ( i − 1 , k ) f(i-1,k) f(i−1,k)可以通过在算 f ( i , j ) f(i,j) f(i,j)的时候,也同时取出来,所以只需时间复杂度 O ( N 2 ) O(N^2) O(N2)

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2222;
int f[N][N];
int n, a[N];
int b[N];
int c[N];
signed main() {cin >> n;for (int i = 1; i <= n; i++) {cin >> a[i];b[i] = a[i];}int cnt = 0;sort(b + 1, b + n + 1);for (int i = 1; i <= n; i++) {if (i == 1 || b[i] != b[i - 1]) {++cnt;}c[cnt] = b[i];}for (int i = 1; i <= n; i++) {int minv = f[i - 1][1];for (int j = 1; j <= cnt; j++) {minv = min(minv, f[i - 1][j]);f[i][j] = minv + abs(c[j] - a[i]);}}int res = f[n][1];for (int i = 2; i <= cnt; i++) {res = min(res, f[n][i]);}reverse(a + 1, a + 1 + n);for (int i = 1; i <= n; i++) {int minv = f[i - 1][1];for (int j = 1; j <= cnt; j++) {minv = min(minv, f[i - 1][j]);f[i][j] = minv + abs(c[j] - a[i]);}}for (int i = 1; i <= cnt; i++) {res = min(res, f[n][i]);}cout << res << endl;return 0;
}

E. Sonya and Problem Wihtout a Legend

题意:

给定一个长度为 N N N的 A A A序列,现在要把 A A A序列改成严格单调递增的序列 B B B,每次修改的花费为 ∣ A i − B i ∣ |A_i-B_i| ∣Ai​−Bi​∣,现在问把序列改成严格单调递增的最小花费为多少?

思路:

根据严格单调递增可知 B i + 1 > B i B_{i+1}>B_{i} Bi+1​>Bi​,所以 B i + 1 − 1 ≥ B i B_{i+1}-1≥B_{i} Bi+1​−1≥Bi​,所以 B i + 1 − ( i + 1 ) ≥ B i − i B_{i+1}-(i+1)≥B_{i}-i Bi+1​−(i+1)≥Bi​−i,所以构造新数组 C i = B i − i C_i=Bi-i Ci​=Bi−i,此时问题转化为把 C C C数组改为非严格单调递增的序列的最小花费?此时就是上面那个问题了。

#include <bits/stdc++.h>
using namespace std;
const int N = 3333;
#define ll long long
int n, m;
int a[N];
ll f[N][N];
int b[N];
int main() {cin >> n;for (int i = 1; i <= n; i++) {cin >> a[i];a[i] -= i;b[i] = a[i];}sort(a + 1, a + n + 1);m = unique(a + 1, a + n + 1) - (a + 1);for (int i = 1; i <= n; i++) {ll minv = f[i - 1][1];for (int j = 1; j <= m; j++) {minv = min(f[i - 1][j], minv);f[i][j] = minv + abs(b[i] - a[j]);}}ll res = 1e18;for (int i = 1; i <= m; i++) {res = min(res, f[n][i]);}cout << res << endl;
}

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

[USACO08FEB]Making the Grade G 和 CF714E相关推荐

  1. Making The Grade G

    Making The Grade G   原题传送门: luogu P2893 USACO08FEB   题目大意: 给定一个长度为 N N N 的序列 A A A 让你构造一个长度也为 N N N ...

  2. 16_python_面向对象

    一.面向对象和面向过程的区别 1.面向对象:一切以对象为中心.有相同属性和动作的结合体叫做对 优点:易维护.易复用.易扩展,由于面向对象有封装.继承.多态性的特性,可以设计出低耦合的系统,使系统 更加 ...

  3. 刻意练习:Python基础 -- Task10. 类与对象

    背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...

  4. Python基础,面向对象

    几个名词知识: 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例. 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中 ...

  5. Python-面向对象 (二 继承)

    一 继承   基类定义例如以下: class people:     #define attribute     name = ''     age  = 0     #define private ...

  6. python 类的继承,类中的函数调用以及类输入数组

    第一部分,类的继承 先给出一个例子: class People(): #定义类,要大写,python 2中要在括号里加如object这个单词def __init__(self,n,a,w): #定义一 ...

  7. javaweb学习总结三(枚举)

    一:枚举的概念 定义特定的数据,尤其像一些状态位. 二:定义枚举类 1:定义枚举,其中Grade枚举可以看做类,A.B.C.D.E可以看做对象,因为它定义了有参数的构造方法,所以 对象后面必须带参数. ...

  8. C++this指针操作

    在这里总结一下this 指针的相关知识点. 首先,我们都知道类的成员函数可以访问类的数据(限定符只是限定于类外的一些操作,类内的一切对于成员函数来说都是透明的),那么成员函数如何知道哪个对象的数据成员 ...

  9. 两只小熊队高级软件工程第七次作业敏捷冲刺7

    团队的作业:学生信息管理系统 队员学号: 周菲(队长) 201810812007 孔繁燕   201810812001 Alpha敏捷冲刺: 1. 站立式会议照片: 2.每个人的工作: 周菲: 今天已 ...

最新文章

  1. linux 大量的TIME_WAIT解决办法
  2. 快手超大规模集群调度优化实践
  3. 【Netty】从 BIO、NIO 聊到 Netty
  4. Salesforce平台支持多租户Multi tenant的核心设计思路
  5. 静态路由(原理+实验)
  6. 详解C调用lua脚本效率测试
  7. jquery通过ajax向后台发送(checkbox)数组,并在后台接收,(发送的数据是checkedbox)...
  8. vsco_VSCO重新设计:更直观,更简化的界面
  9. 【入门篇】Nginx + FastCGI 程序(C/C++) 搭建高性能web service的Demo及部署发布
  10. 常见算法工程师面试题总结(机器学习,深度学习)
  11. love2d 编译 android,Love2D游戏脚本在windows平台下打包exe发布教程
  12. 学GIS的你,是时候自己做张中国地图了(附行政区划数据下载)
  13. 计算机技术在生物学中的应用鲁东大学,生物科学与技术学院
  14. Docker容器网络模式与数据管理
  15. 用Boost::spirit库写C++的源代码解析器(一) 一个简单的例子:解析enum的解析器雏形
  16. Kaggle项目之Mobile App Store
  17. Java集合可分成什么类_java.util包含Java中大量工具类、集合类等,例如Arrays、List、Set等。...
  18. 二叉树广度和深度遍历的全部算法
  19. 阿里大数据ACP认证对找工作到底有用嘛?
  20. 什么是进程、进程的概念?

热门文章

  1. c语言合法自定义标识符_合法的C语言标识符有哪些规定
  2. 数据中心该如何节省资源减少能源浪费
  3. 一个Java工程师的自我修养_程序员自我修养
  4. [ 网络协议篇 ] vlan 详解之 MUX vlan 详解
  5. linux shell echo 换行,shell echo 换行
  6. 【财富空间】彭剑锋:中国企业如何赢得未来?这6个关键词最值得关注
  7. wap2app去除系统自带的导航栏
  8. 返回类型和return语句
  9. 【附中秋中奖名单】2年出版2本书带给我的改变,分享程序员写书和写博客的技巧...
  10. 使用DroneKit控制无人机