- 学术
【答疑】P2339 Turning in Homework
- 2025-7-30 14:18:24 @
P2339 Turning in Homework
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
/*
题意:走廊上有 C 个教室,第 i 个坐标为 x_i,老师最早 t_i 接收作业。
派大星从 0 出发,速率 1,每交完一门才可走,最后必须走到 B 离开。
求最早离开时间。
做法:经典区间 DP。
f[l][r][0]:区间 [l,r] 尚未交,当前位置在 l(刚交完 l-1)所需最早时刻
f[l][r][1]:同理,当前位置在 r(刚交完 r+1)
先把区间设为 [1,C],每次只缩外层(一定优于先缩内部)。
转移时记录“走到下一端 + 等待老师”的最小完工时刻。
长度从大到小递推,最后区间缩成单点 [i,i],再加 |x_i-B| 取最小即可。
复杂度 O(C²),C≤1000 轻松通过。
*/
const int N=1005;
const ll INF=4e18;
struct P{int x,t;} a[N];
ll f[N][N][2];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int c,h,B;
if(!(cin>>c>>h>>B)) return 0;
for(int i=1;i<=c;i++) cin>>a[i].x>>a[i].t;
sort(a+1,a+c+1,[](P A,P B){return A.x==B.x?A.t<B.t:A.x<B.x;});
for(int i=0;i<=c+1;i++)
for(int j=0;j<=c+1;j++)
f[i][j][0]=f[i][j][1]=INF;
f[1][c][0]=max<ll>(a[1].x,a[1].t);
f[1][c][1]=max<ll>(a[c].x,a[c].t);
for(int d=c-2;d>=0;d--) // 区间长度
for(int l=1;l+d<=c;l++){
int r=l+d;
// 更新 f[l][r][0](站在 l)
ll v=INF;
if(l>1) v=min(v,f[l-1][r][0]+(ll)(a[l].x-a[l-1].x));
if(r<c) v=min(v,f[l][r+1][1]+(ll)(a[r+1].x-a[l].x));
f[l][r][0]=max(v,(ll)a[l].t);
// 更新 f[l][r][1](站在 r)
v=INF;
if(r<c) v=min(v,f[l][r+1][1]+(ll)(a[r+1].x-a[r].x));
if(l>1) v=min(v,f[l-1][r][0]+(ll)(a[r].x-a[l-1].x));
f[l][r][1]=max(v,(ll)a[r].t);
}
ll ans=INF;
for(int i=1;i<=c;i++){
ll best=min(f[i][i][0],f[i][i][1]);
ans=min(ans,best+abs(a[i].x-B));
}
cout<<ans<<'\n';
return 0;
}
0 条评论
目前还没有评论...