这不是DP,不是DFS
这里是BFS
为什么采用BFS?
因为蒟蒻不会DP/DFS
因为BFS思路像DFS一样简单,复杂度可以像DP一样小
只需小小的优化:
决定第i个垃圾后:
由于生命值越大,离井口高度越小才可能是最优解
所以上图中除了已经标出的点之外,永远不可能取得最优解
那么剩下的点都可删去
离井口的高度 ∈ [ 0 , D ] \in[0,D] ∈[0,D]
时间复杂度 Θ ( D G ) \Theta(DG) Θ(DG)
D ∈ [ 2 , 100 ] , G ∈ [ 1 , 100 ] D\in[2,100],G\in[1,100] D∈[2,100],G∈[1,100]
只要从右到左,从下到上按高度递减取点即可
堆实现
struct Q{
int m,t,h;
bool operator<(const Q x)const{//重载小于号反向
if(m!=x.m)return x.m<m;
if(t!=x.t)return x.t>t;
return x.h<h;
}
};
priority_queue<Q>q;//大根堆
关键部分
q.push((Q){0,10,d});
int maxlive=10,minout=inf;
int num=0,minh=inf;
Q tmp;
for(int i=0;tmp=q.top(),i=tmp.m,!q.empty()&&i<g;)
{
q.pop();
if(a[i].t>tmp.t)continue;//卡门死了,停止
if(i>num)num=tmp.m,minh=inf;
if(tmp.h<minh)
{
if(tmp.h-a[i].h<=0)//卡门出去了
{
minout=a[i].t;
break;
}
q.push((Q){i+1,tmp.t,tmp.h-a[i].h});
q.push((Q){i+1,tmp.t+a[i].f,tmp.h});
maxlive=max(maxlive,tmp.t+a[i].f);
minh=tmp.h;
}
}