社区讨论

求助,跳房子90分,最后一个点WA了

P3957[NOIP 2017 普及组] 跳房子参与者 4已保存回复 5

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
5 条
当前快照
1 份
快照标识符
@mi7wzssf
此快照首次捕获于
2025/11/21 04:59
4 个月前
此快照最后确认于
2025/11/21 04:59
4 个月前
查看原帖
CPP
# include <bits/stdc++.h>
using namespace std;

const int N = 5e5 + 10;
const int inf = INT_MAX;

long long n,d,k,sum = 0;
long long pos[N],score[N],f[N],q[N];

bool check(int x)
{
  long long min_step = max(d - x,1ll * 1),max_step = d + x;
  memset(q,0,sizeof(q));
  f[0] = 1ll * 0;
  int h = 1,t = 0,j = 0;
  for(int i = 1;i <= n;i++) f[i] = -inf - 1;
  for(int i = 1;i <= n;i++)
  {
  	while(pos[i] - pos[j] >= min_step && j < i)
  	{
  	  while(h <= t && f[q[t]] <= f[j]) t--;
      q[++t] = j;
      j++;
    }
    while(h <= t && pos[i] - pos[q[h]] > max_step) h++;
    if(h <= t) f[i] = f[q[h]] + score[i];
  }
  long long ans = f[1];
  for(int i = 1;i <= n;i++) 
    ans = max(ans,f[i]);
  return ans >= k;
}

int main()
{
  //freopen("1.in","r",stdin);
  //freopen(".out","w",stdout);
  scanf("%lld%lld%lld",&n,&d,&k);
  for(int i = 1;i <= n;i++)
  {
    scanf("%lld%lld",&pos[i],&score[i]);
    if(score[i] > 0) sum += score[i];
  }
  if(sum < k) {puts("-1");return 0;}
  int l = 0,r = max(d,pos[n]),ans = 0;
  while(l <= r)
  {
  	int mid = (l + r) >> 1;
  	if(check(mid)) r = mid - 1,ans = mid;
  	else l = mid + 1;
  }
  printf("%d\n",ans);
  return 0;
}

回复

5 条回复,欢迎继续交流。

正在加载回复...