#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int g[5005],b[5005],d,m,n;
int dp[5005][5005];
int q[5005];
int flag;
int head,tail;
int main()
{
scanf("%d%d%d",&n,&d,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&g[i],&b[i]);
if(b[i]-b[i-1]>d)//判断猴子能不能跳到当前输入的点
{
flag=i-1;
break;
}
}
dp[0][1]=g[1];
if(flag==0)//如果猴子能跳到所有的点(不考虑猴子弹跳次数的限制的跳不到)
{
flag=n;//那么flag没有被赋值 flag的值是初值0 那么还要把flag重新赋值成n(代表能跳到所有点)
}
for(int i=1;i<=m;i++)
{
head=tail=0;q[head]=0;//注意每次最外层关于i的循环时 q[head]必须清零 不清零的话 上一层i的值会残留下来 而head之后的值不用清零 因为会被tail++给覆盖
for(int j=1;j<=flag;j++)
{
while(head<tail&&b[j]-b[q[head]]>d)
{
head++;
}
dp[i][j]=dp[i-1][q[head]]+g[j];
while(head<tail&&dp[i-1][q[tail-1]]<dp[i-1][j])
{
tail--;
}
q[tail++]=j;
}
}
int ans=-1;
for(int i=1;i<=n;i++)
{
ans=max(ans,dp[m][i]);
}
printf("%d",ans);
return 0;
}
#include<cstring>
#include<algorithm>
using namespace std;
int g[5005],b[5005],d,m,n;
int dp[5005][5005];
int q[5005];
int flag;
int head,tail;
int main()
{
scanf("%d%d%d",&n,&d,&m);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&g[i],&b[i]);
if(b[i]-b[i-1]>d)//判断猴子能不能跳到当前输入的点
{
flag=i-1;
break;
}
}
dp[0][1]=g[1];
if(flag==0)//如果猴子能跳到所有的点(不考虑猴子弹跳次数的限制的跳不到)
{
flag=n;//那么flag没有被赋值 flag的值是初值0 那么还要把flag重新赋值成n(代表能跳到所有点)
}
for(int i=1;i<=m;i++)
{
head=tail=0;q[head]=0;//注意每次最外层关于i的循环时 q[head]必须清零 不清零的话 上一层i的值会残留下来 而head之后的值不用清零 因为会被tail++给覆盖
for(int j=1;j<=flag;j++)
{
while(head<tail&&b[j]-b[q[head]]>d)
{
head++;
}
dp[i][j]=dp[i-1][q[head]]+g[j];
while(head<tail&&dp[i-1][q[tail-1]]<dp[i-1][j])
{
tail--;
}
q[tail++]=j;
}
}
int ans=-1;
for(int i=1;i<=n;i++)
{
ans=max(ans,dp[m][i]);
}
printf("%d",ans);
return 0;
}