给你n对二元组
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <queue>
#include <map>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <set>
#include <cmath>
using namespace std;
typedef long long ll;
const int MAXN=4e4+10;
ll dp[MAXN];
int rp[MAXN],gp[MAXN];
int n,Rlim;
bool jd(int L)
{
multiset<ll> st;
deque<int> que;
int l=1;
bool valid=true;
for(int i=1; i<=n; i++)
{
if(gp[i]-gp[i-1]>L)
{
valid=false;
break;
}
while(l<=n && gp[i]-gp[l-1]>L) l++;
while(!que.empty() && gp[i]-gp[que.front()-1]>L)
{
int v=que.front();
que.pop_front();
if(!que.empty())
st.erase(dp[v]+rp[que.front()]);
}
while(!que.empty() && rp[que.back()]<=rp[i])
{
int v=que.back();
que.pop_back();
if(!que.empty())
st.erase(dp[que.back()]+rp[v]);
}
if(!que.empty())
st.insert(dp[que.back()]+rp[i]);
que.push_back(i);
dp[i]=1LL<<60;
if(!st.empty()) dp[i]=*st.begin();
dp[i]=min(dp[i],rp[que.front()]+dp[l-1]);
// cout<<i<<" : "<<dp[i]<<endl;
}
// cout<<Rlim<<endl;
return dp[n]<=Rlim;
}
int main()
{
// freopen("/home/sunshine/in","r",stdin);
while(~scanf("%d%d",&n,&Rlim))
{
for(int i=1; i<=n; i++)
{
scanf("%d%d",rp+i,gp+i);
gp[i]+=gp[i-1];
}
int l=0,r=gp[n];
int ans=-1;
// cout<<jd(1)<<endl;
while(l<=r)
{
int mid=(l+r)/2;
if(jd(mid))
{
ans=mid;
r=mid-1;
}
else
l=mid+1;
}
printf("%d\n",ans);
}
return 0;
}