猴子 lnsyoj

#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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值