link
$solution:$
演算法一通過觀察範圍發現 $q\leq1000$ ,所以直接暴力拆點 $dp$ 。時間複雜度 $o(1000m)=o(能過)$ 。
演算法二因為有 $a\times x^2+b\times x+c$ 考慮斜率優化。
設 $f_i$ 表示走完第 $i$ 條邊的最小煩躁值,則 $f_i=\min\\space (u_i=v_j,p_i\geq q_j)$ 。
可以發現現在的瓶頸是如何快速處理 $u_i=v_j,p_i\geq q_j$。
通過演算法一可以得到通過將 $p$ 排序處理順序,然後就將決策邊放入其 $v_j$ 中 。
每次取出 $q$ 值,插入相對應的 $v$ 中既可以找到決策點。
然後就斜率優化即可。
#include#includeview code#include
#include
#include
#include
using
namespace
std;
inline
intread()
while(c>='
0'&&c<='9')
return f*ans;
}const
int maxn=200001
;deque
que[maxn];
intn,m,a,b,c,f[maxn];
struct
nodeg[maxn];
vector
ve[maxn];
vector
pre[maxn];
int x(int id)
int y(int id)
void insert(int
id) que[ps].push_back(las1);
}que[ps].push_back(id);
//printf("id:%d ps:%d front:%d\n",id,ps,que[ps].front());
}void del(int
id)que[ps].push_front(las2);
}return;}
int minn=int_max;
int calc(int g)
intmain()
del(id);
if(que[ps].empty()) continue
; f[id]=f[que[ps].front()]+calc(g[id].p-g[que[ps].front()].q);
pre[g[id].q].push_back(id);}}
//for(int i=1;i<=m;i++) printf("x(%d):%d y(%d):%d\n",i,x(i),i,y(i));
//for(int i=1;i<=m;i++) printf("f(%d):%d\n",i,f[i]);
for(int i=1;i<=m;i++) if(g[i].v==n) minn=min(minn,f[i]+g[i].q);
printf(
"%d\n
",minn);return0;
}
NOI2019 回家路線
點此看題 首先可以用暴力dpdp dp艹過去,設dp i j dp i j dp i j 為到了i ii點的時間是j jj的最小花費,由於時間是單向流逝的,我們可以先把邊按出發時間排序,用邊轉移,列舉到達出發點的時間jjj d p y i q i dp x i j cost p i j dp y i...
NOI2019 回家路線(最短路,斜率優化)
終於把這鬼玩意弄完了 為什麼寫的這麼醜 順便吐槽 routesea 最短路的狀態很顯然 f i 表示從第 i 條線下來的最小代價。首先明顯要把那個式子拆開。直覺告訴我們這應該是個斜率優化。f i min f j a p i q j 2 b p i q j c x i y j,p i ge q j f...
LOJ 3156 NOI2019 回家路線
傳送門 明明可以bfs bfsbf s寫了個dij dijdi j把自己強行玩wawa wa有2種做法 第一種 考慮對於同乙個點的入邊i,j i,ji,j轉移給出邊xxx 把式子列出來後發現是乙個標準的斜率優化 在凸包上二分就可以了 複雜度o m logm o mlogm o mlog m 第二種 ...