1 条题解
-
0
自动搬运
来自洛谷,原作者为

bztMinamoto
**搬运于
2025-08-24 22:01:47,当前版本为作者最后更新于2018-08-12 13:58:22,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
表示完全看不懂楼下的大佬们说啥……特别是某绿……某c姓大佬
来说说个人的理解吧
大佬们说:考虑当前的数和之前的最大数,(默认,因为如果已经满足非降了)为了让它非降,我们要在区间里找到一个数,使减小到,增大到,那么可以发现,不管取的数是什么,代价都是
不难看出,减小的越多,后面的序列越容易变成非降,那么只要让减小到就好了
看到这里,我一直有一个疑问,如果令减小到之后,序列不满足非降了怎么办?
仔细想了想,实际上应该是这样的:为了让序列非降,不能小于之前的最大值。而由于是整个序列的最大值,如果它之前的最大值小于等于,那么将减小到仍能保证序列是非降的。否则的话,大于小于,仍是在区间内,那么移动的代价是,所以用于更新答案是没有问题的
那么这里为什么要让减到最小呢?这是因为和不论如何调整,他们的代价之和都已经不变了,但问题是他们目前选的最优方案并不是之后的最优。为了满足他们在之后最优,只有把减小到,才能保证之后更有可能非降。
概括一下,对于当前的数,无论最优解如何,对答案的贡献是一定的。而为了保证之后的解也最优,令减小到,可以保证之后的解最优,且不会影响当前的最优解
代码好短……
//minamoto #include<cstdio> #include<iostream> #include<queue> using namespace std; #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) char buf[1<<21],*p1=buf,*p2=buf; inline int read(){ #define num ch-'0' char ch;bool flag=0;int res; while(!isdigit(ch=getc())) (ch=='-')&&(flag=true); for(res=num;isdigit(ch=getc());res=res*10+num); (flag)&&(res=-res); #undef num return res; } priority_queue<int> q; int n;long long ans; int main(){ n=read(); while(n--){ int x=read();q.push(x); if(x<q.top()){ ans+=q.top()-x; q.pop();q.push(x); } } printf("%lld\n",ans); return 0; }
- 1
信息
- ID
- 3572
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者