题解 P4393 【[BOI2007]Sequence 序列问题】

Solution:

对于每个很大的数,基于贪心,我们显然要让它合并次数尽可能少,以保证最终总代价最小。

如图:

考虑中间那个最大的 $maxn$,很显然,将其与其它的合并代价显然更大,所以,我们不可能先用 $maxn$ 去和其它的合并。

但是,由于最终目标长度为1,所以无论如何,$maxn$ 终将被合并,可以先考虑将比它小的全部合并,最后再与它合并,以减少它参与合并的次数。

不难想到,可以先将 $maxn$ 左边全部合并,再将其右边全部合并,最后,再让左右两部分与它合并,这样可以保证比先合并 $maxn$ 与其它的更优。

然后,该问题就被分成两个小问题,合并左边与右边。

注意到,如果一个数左边比它小,那么总有一天,总有一年会向它合并过来,也就是说,它不可避免的向左对答案产生一次贡献,右边一样同理。

若一个数左边比它大,那么它肯定会在某个时刻并上去,那么对答案产生贡献的是它左边的数,右边同理。

总之,一个数的左邻比它小,它会产生一次贡献,右舍比它小,就会再产生一次贡献,累计答案即可。

#include<bits/stdc++.h>
using namespace std;

int n,hxt[10001000];
long long ans;

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&hxt[i]);
	for(int i=2;i<=n;i++) ans+=max(hxt[i],hxt[i-1]);
	printf("%lld",ans);
	return 0;
}

原文地址:https://www.cnblogs.com/wxg-Jay/p/12239551.html

时间: 2024-07-30 05:52:52

题解 P4393 【[BOI2007]Sequence 序列问题】的相关文章

Python学习笔记之-sequence序列

1:sequence(序列)是一组有顺序的元素的集合 : (严格的说,是对象的集合,但鉴于我们还没有引入"对象"概念,暂时说元素) 序列可以包含一个或多个元素,也可以没有任何元素. 我们之前所说的基本数据类型,都可以作为序列的元素.元素还可以是另一个序列,以及我们以后要介绍的其他对象. 序列有两种:tuple(定值表: 也有翻译为元组) 和 list (表) >>>s1 = (2, 1.3, 'love', 5.6, 9, 12, False)         # s

oracle的sequence序列

Sequence:序列是一个数据对象,可以用来生成唯一的整数.是数据库里独立的对象,不依赖任何表,为oracle所特有.用来自动生成主键值,可以用sequence的地方:inert语句的子查询中,update的set等.创建序列 :Create sequence seqname -increament by 1//每次增长1 -start with 1//从1开始增长 -maxvalue 100//最大值是100,nomaxvalue:不设最大值 -nocycle//一直累加没有循环 -noca

Python sequence (序列)

序列简介 sequence 是一组有序元素的组合 序列可以是多个元素,也可以一个元素都没有 序列有2种:tuple(定值表).List(表) D:\python\Python_Day>python Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)] on win32 Type "help", "copyright", "credit

PAT甲题题解-1051. Pop Sequence (25)-堆栈

将1~n压入最多为m元素的栈 给出k个出栈序列,问你是否能够实现. 能输出YES 否则NO 模拟一遍即可,水题. #include <iostream> #include <cstdio> #include <string.h> #include <algorithm> using namespace std; const int maxn=1005; int m,n,k; int seq[maxn]; int stacks[maxn]; int rear=

[BOI2007] Sequence

题目描述 对于一个给定的序列a1, -, an,我们对它进行一个操作reduce(i),该操作将数列中的元素ai和ai+1用一个元素max(ai,ai+1)替代,这样得到一个比原来序列短的新序列.这一操作的代价是max(ai,ai+1).进行n-1次该操作后,可以得到一个长度为1的序列. 我们的任务是计算代价最小的reduce操作步骤,将给定的序列变成长度为1的序列. 输入输出格式 输入格式: 第一行为一个整数n( 1 <= n <= 1,000,000 ),表示给定序列的长度. 接下来的n行

题解-BOI 2004 Sequence

Problem bzoj & Luogu 题目大意: 给定序列\(\{a_i\}\),求一个严格递增序列\(\{b_i\}\),使得\(\sum \bigl |a_i-b_i\bigr|\)最小 Thought 正序:直接对应 逆序:取中位数(证明:"医院设置") 最优解一定是分段 每一段台阶式上升 每一段选取中位数 沙漏型左偏树 合并区间 选取中位数 upd:貌似不需要沙漏型? Solution 前置技能:小学奥数.可并堆 和上面类似,先不考虑严格上升,即先考虑非严格上升 序

oracle 主键生成策略-sequence序列+trigger触发器

oracle中设置表的主键字段为自增序列(实例)1.首先创建一个表(如日志表) //删除库表中存在的日志表drop table S_LOG_INFO cascade constraints;//新建日志表create table S_LOG_INFO ( PRIMARYKEY NUMBER not null,//主键 USERACCOUNT VARCHAR2(50),//操作用户账号 USERNAME VARCHAR2(100),//操作用户 OPERATIONTIME DATE,//操作时间

题解 P2642 【双子序列最大和】

前言 其实这道题的关键就是在于预处理,其方法类似于 合唱队形 正文 求最大子段和 要想求出双子序列最大和,首先我们要会求出最大子段和 最大子段和的求值方法很简单 定义 \(f_i\) 为以第 \(i\) 个数结尾的最大子段和 #include <bits/stdc++.h> using namespace std; int f[1000010],a[1000010]; int main(){ int n; cin>>n; for(int i=1;i<=n;i++)cin>

【题解】 [NOI2009]变换序列 (二分图匹配)

懒得复制,戳我戳我 Solution: 这个题面出的很毒瘤,读懂了其实是个板子题qwq 题面意思:有个\(0\)至\(N-1\)的数列是由另一个数列通过加减得到的,相当于将\(A_i\)变成\(i\),每一步的代价计算就是\(min(A_i-i,N-(A_i-i))\),并且\(A_i\left(0<=i<N\right)\)互不相同,读入代价,要求字典序最小的满足要求的数列 我们设读入的为\(w[i]\) 思路其实很简单,\(i\)只可能是由\(i-w[i]\) 或者 \(i+w[i]\)