2021年 7月 1日
まえがき
やっほ〜
7月になってから初めての投稿だよ。
今日は7月ってことで、ジュライジュライした記事を心がけていきたいとおもっていま〜す。
チュドーンッ!!!
まちがええた、これは地雷だ (うん)
健康管理
何した
ありが今日も働いているから俺も働いている。
具体的に
今日解いた問題
ABC095 D- Static Sushi
- [寿司,全探索,累積]
まぁ、寿司を食った瞬間,もしくは一歩も動かずに店を出る。っていうのは分かると思う。
つまり、店を出る位置は0,x1,x2,x3,...,xnのいずれかということ。
解法 1. 時計回りに i 個食べた後、0の位置に戻ってから何個逆時計周りに食べるか(n-i個まで食べれる)を決める。(一番良いのは何個かっていうのは前処理で求められる) 2. その逆もやる。
食べる道順的なのは実は少なくて…
1. 時計回りに何個か食べた後退店
2. 反時計回りに何個か食べた後退店
3. 時計回りに何個か食べた後、0 の位置に戻って反時計回りに何個か食べて退店
4. 反時計回りに何個か食べた後,0 の位置に戻って時計回りに何個か食べて退店
(0の位置に戻って、というのはわかりやすさのためにそうしています。)
時計回りに1個食べた後反時計回りに歩いて1個、その後時計回りに歩いて食べる。
というのは無駄です。
累積で、時計回りにi個まで食べれるとき、+になるカロリーの値の最大値をO(1)で取れるようにしました。
int main() { ll n, c; cin >> n >> c; vector<ll> x(n), v(n); rep(i,n) cin >> x[i] >> v[i]; // 左回りに取っていった時の累積 vector<ll> left(n+1); ll pos = 0; left[0] = 0; rep(i,n){ left[i+1] = left[i] + v[i] - (x[i] - pos); pos = x[i]; } vector<ll> right(n+1); right[0] = 0; pos = c; rep(i,n){ right[i+1] = right[i] + v[n-i-1] - abs(x[n-i-1] - pos); pos = x[n-i-1]; } // 左から i 個取れるときの最大 vector<ll> max_left(n+1); rep(i,n+1){ max_left[i] = left[i]; if(i != 0) chmax(max_left[i], max_left[i-1]); } vector<ll> max_right(n+1); rep(i,n+1){ max_right[i] = right[i]; if(i != 0) chmax(max_right[i], max_right[i-1]); } ll ans = 0; rep(i,n+1){ // 左からi個食べる ll tmp = left[i]; chmax(ans,tmp); if(i == n) // 全部食った { continue; } else { // 右から n - i 個食える if(i != 0){ // 0 まで戻ってくる tmp -= x[i-1]; } tmp += max_right[n-i]; chmax(ans,tmp); } } rep(i,n+1){ // rightからi個食べる ll tmp = right[i]; chmax(ans,tmp); if(i == n) // 全部食った { continue; } else { // 右から n - i 個食える if(i != 0){ // i = 1 なら x[n-1]; tmp -= (c-x[n-i]); } tmp += max_left[n-i]; chmax(ans,tmp); } } cout << ans << endl; }
あとがき
以下は毎回記事に貼っているテンプレート
基本的に読書はTwitterで絡みのある人だけだと思いますが、僕のブログだけ見てるって人もいるかもしれないので、一応自己紹介っぽいことをしている記事を貼っておきます - 瑞々しぃにぼしの自己紹介(自己紹介の記事です)