P4801 [CCO 2015]饥饿的狐狸

2023-10-31 02:59
文章标签 2015 饥饿 cco p4801 狐狸

本文主要是介绍P4801 [CCO 2015]饥饿的狐狸,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

R e s u l t Result Result

...


H y p e r l i n k Hyperlink Hyperlink

https://www.luogu.com.cn/problem/P4801


D e s c r i p t i o n Description Description

n n n个东西,第 i i i个物品的温度是 a i a_i ai,有一杯温度为 w w w的水(你可以认为它的水量无穷)

吃掉每个物品的代价是这次吃的物品的温度与上次吃的物品的温度差值,在每次吃东西的时候,你也可以选择先喝一杯水,这样就默认你上次吃的物品是水

假设你已经喝了一杯水,试着安排一种吃东西的顺序,使得代价最小/最大

数据范围: n ≤ 1 0 5 , w ≤ 1 0 9 n\leq 10^5,w\leq 10^9 n105,w109


S o l u t i o n Solution Solution

贪心,排序是显而易见的

考虑最大价值,显然我们是每次选择最大的和最小的判断即可,中间判断是否喝水更优就好了,注意初始化要喝一杯水

最小价值显然是升序或者倒序吃东西,如果没有喝水的限制,答案显然是 a n − a 1 a_n-a_1 ana1

考虑水的温度对答案的贡献
假设 w ∈ [ a 1 , a n ] w\in[a_1,a_n] w[a1,an],显然我们可以在最后一个与 a 1 a_1 a1相等的食物后面喝一杯水,就能抵消刚开始喝的那杯水产生的代价,即答案为 a n − a 1 a_n-a_1 ana1
假设 w < a 1 w<a_1 w<a1,由于题目要求那杯水必须喝,所以答案要加上 a 1 − w a_1-w a1w,答案变成 a n − w a_n-w anw
假设 w > a n w>a_n w>an,跟上面的一个道理,此时我们反过来吃,答案要加上 w − a n w-a_n wan,答案变成 w − a 1 w-a_1 wa1

最终化成的式子就是 max ⁡ { 0 , a n − w } + max ⁡ { 0 , w − a 1 } \max\{0,a_n-w\}+\max\{0,w-a_1\} max{0,anw}+max{0,wa1}

时间复杂度: O ( n log ⁡ n ) O(n\log n) O(nlogn)


C o d e Code Code
#include<cstdio> 
#include<cctype>
#include<algorithm>
#define LL long long
using namespace std;
int n,lst;
LL maxn,w,a[100010],now,l,r;
inline LL read()
{char c;LL d=1,f=0;while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;return d*f;
}
signed main()
{n=read();w=read();for(register int i=1;i<=n;i++) a[i]=read();sort(a+1,a+1+n);printf("%lld ",max(0ll,a[n]-w)+max(0ll,w-a[1]));lst=w;l=1;r=n;now=0;for(register int i=1;i<=n;i++) if(i&1) now+=max(abs(a[l]-lst),abs(a[l]-w)),lst=a[l++];else now+=max(abs(a[r]-lst),abs(a[r]-w)),lst=a[r--];maxn=now;lst=w;l=1;r=n;now=0;for(register int i=1;i<=n;i++) if(i&1) now+=max(abs(a[r]-lst),abs(a[r]-w)),lst=a[r--];else now+=max(abs(a[l]-lst),abs(a[l]-w)),lst=a[l++];printf("%lld",max(maxn,now));
}

这篇关于P4801 [CCO 2015]饥饿的狐狸的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

CF Bayan 2015 Contest Warm Up B.(dfs+暴力)

B. Strongly Connected City time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/475/probl

CF Bayan 2015 Contest Warm Up A.(模拟+预处理)

A. Bayan Bus time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output 题目链接: http://codeforces.com/contest/475/problem/A The fi

2015年校赛总结

题目名为“校赛总结”,其实更想换成“Rainbow为什么五题滚粗?!”。作为今年校赛大二没拆的两个队伍之一,结果打成这样,没脸见人了,总结起来就是我认为自己今天SB了。主要有以下几点: 1.我今天状态的确不好,最后卡的那道B题跟去年在农大校赛上遇见的那题类似,在最后那段时间我已经有思路了,可是由于当时不敢写。等到最后15分钟才开始敲,加上我用很麻烦的Dijstra那种方法,调试起来好多细节要处理

百度之星 2015 复赛 1001 (数长方形)

数长方形    Accepts: 595    Submissions: 1225  Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description 小度熊喜欢玩木棒。一天他在玩木棒的时候,发现一些木棒会形成长方形

百度之星 2015 初赛(1) 1002 找连续数

找连续数      Accepts: 401      Submissions: 1911  Time Limit: 2000/1000 MS (Java/Others)      Memory Limit: 32768/32768 K (Java/Others) Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是

2015多校联合训练第三场Work(hdu5326)

题意: a是b的上司,b是c的上司,则a是c的上司,问构成一个树种,有多人是 k个人的上司 思路: 先找出root,然后dfs一下就行 #include <bits/stdc++.h>#define LL long longusing namespace std;const int MAXN = 1e6;int f[105];int n, k;int mp[101][101];

2015年多校联合训练第三场RGCDQ(hdu5317)

题意: f(i)代表i数中有的素数的种数,给出区间[l,r],求区间内max(gcd(f(i))), 由于i最大是1e6,2*3*5*7*11*13*17>1e6,故最多不超过7种素数, 先打表打出1e6内的素数种数表,然后用sum[i][j]代表1-i个数中,还有j个素数的个数,最后用sum[r][j] - sum[l-1][j]求出区间内含有j个素数的数的个数,暴力找出1,2,3,4,5

2015多校联合训练第一场Tricks Device(hdu5294)

题意:给一个无向图,给起点s,终点t,求最少拆掉几条边使得s到不了t,最多拆几条边使得s能到t 思路: 先跑一边最短路,记录最短路中最短的边数,总边数-最短边数就是第二个答案 第一个答案就是在最短路里面求最小割,也就是求最大流,然后根据最短路在建个新图,权为1,跑一边网络流 模板题,以后就用这套模板了 #include <iostream>#include <cstdio>#incl

2015多校联合训练第一场Assignment(hdu5289)三种解法

题目大意:给出一个数列,问其中存在多少连续子序列,子序列的最大值-最小值< k 这题有三种解法: 1:单调队列,时间复杂度O(n) 2:RMQ+二分,时间复杂度O(nlogn) 3:RMQ+贪心,时间复杂度O(nlogn) 一:RMQ+二分 RMQ维护最大值,最小值,枚举左端点i,二分找出最远的符合的右端点j,答案就是ans += j - i+1;(手推一下就知道) 比如1 2 3

2015年多校联合训练第一场OO’s Sequence(hdu5288)

题意:给定一个长度为n的序列,规定f(l,r)是对于l,r范围内的某个数字a[i],都不能找到一个对应的j使得a[i]%a[j]=0,那么l,r内有多少个i,f(l,r)就是几。问所有f(l,r)的总和是多少。 公式中给出的区间,也就是所有存在的区间。 思路:直接枚举每一个数字,对于这个数字,如果这个数字是合法的i,那么向左能扩展的最大长度是多少,向右能扩展的最大长度是多少,那么i为合法的情况