Codeforces Contest 1107 problem G Vasya and Maximum Profit―― 枚举每个不可控制的量找它所对应区间的数的最大值

匿名 (未验证) 提交于 2019-12-02 23:06:17

Vasya got really tired of these credits (from problem F) and now wants to earn the money himself! He decided to make a contest to gain a profit.

Vasya has n problems to choose from. They are numbered from 1 to n. The difficulty of the i-th problem is di. Moreover, the problems are given in the increasing order by their difficulties. The difficulties of all tasks are pairwise distinct. In order to add the i-th problem to the contest you need to pay ci burles to its author. For each problem in the contest Vasya gets a burles.

In order to create a contest he needs to choose a consecutive subsegment of tasks.

So the total earnings for the contest are calculated as follows:

if Vasya takes problem i to the contest, he needs to pay ci to its author;
for each problem in the contest Vasya gets a burles;

Calculate the maximum profit that Vasya can earn by taking a consecutive segment of tasks.

Input

Each of the next n lines contains two integers di and ci (1≤di,ci≤109,di<di+1).

Output
Print one integer ― maximum amount of burles Vasya can earn.

Examples
inputCopy
5 10
1 15
5 3
6 11
7 2
11 22
outputCopy
13
inputCopy
3 5
1 8
2 19
3 11
outputCopy
0

题意:

给你n种题目,然后给你他们的难度di和花费ci,你能出一段区间的题目,出一道题目可以得到a元,但是要花费区间所有题目的价格,还要花费在这个区间里,相邻两个题目难度差值的平方的最大值,问你最后可以赚最多多少钱。

题解:

区间的变化,a的值和ci的和都是可以预处理出来的,那么我们需要考虑的就是d,我们枚举每一位上的d,记录它最远能够管辖的区间,sta存放的是到当前位置为止,有哪些开头可以管辖到当前位置,和他们最早能管辖到的位置的c的前缀和。举个例子:

有这三个位置,他们一定是单调递减的,因为如果有递增的话,前面那个小的d会被后面大的d取代掉,所以就变成这样。sta记录的就是10的位置和蓝色的线,5的位置和蓝色的线。
那如果现在来了一个6,他就能管辖到5所管辖到的位置,而且这就是为什么要用LIFO的原因。

之后我们还需要有一个东西可以自动排序蓝色线的最小值,在5被删掉的时候,蓝色的线也可以被删掉,因为它无法管辖到下一个位置了。那就用multiset。
其实也是看别人的代码想出来的

#include<bits/stdc++.h> using namespace std; #define ll long long #define pa pair<int,ll> const int N=3e5+5; ll d[N],c[N]; ll dis(int x) {     return (d[x+1]-d[x])*(d[x+1]-d[x]); } int main() {     int n;     ll a,ans=0;     scanf("%d%lld",&n,&a);     for(int i=1;i<=n;i++)     {         scanf("%lld%lld",&d[i],&c[i]);         ans=max(ans,a-c[i]);         c[i]=c[i-1]+a-c[i];     }     stack<pa>st;     multiset<ll>ms;     for(int i=1;i<=n;i++)     {         if(!ms.empty())             ans=max(ans,c[i]-*ms.begin());         ll dist=dis(i),pre=c[i-1];         while(!st.empty()&&dis(st.top().first)<=dist)         {             pre=min(pre,st.top().second);             ms.erase(ms.find(st.top().second+dis(st.top().first)));             st.pop();         }         st.push({i,pre});         ms.insert(dist+pre);     }     printf("%lld\n",ans);     return 0; } 
文章来源: https://blog.csdn.net/tianyizhicheng/article/details/88084667
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!