首页 > 其他分享 >Solution - Atcoder ABC177F I hate Shortest Path Problem

Solution - Atcoder ABC177F I hate Shortest Path Problem

时间:2024-07-09 21:08:47浏览次数:12  
标签:Atcoder infty int Solution ABC177F 考虑 hate 转移

考虑按题目所述的进行 DP
设计状态 \(f_{i, j}\) 代表强制要求 \((i, j)\) 要走向 \((i + 1, j)\) 最小的横坐标之差,这是因为对应的纵坐标之差是确定的。

对于转移,考虑到对于 \(j\not \in [a_i, b_i]\),直接从上面转移下来即可,即 \(f_{i, j}\leftarrow f_{i - 1, j}\)。
对于 \(j\in [a_i, b_i]\),不能往下走,就只能考虑往右走到到 \(b_i + 1\) 处,即 \(f_{i, b_{i} + 1}\leftarrow f_{i - 1, j} + b_{i} + 1 - j\),同时 \(f_{i, j}\) 因为不能走就变为 \(+\infty\)。

需要用个数据结构优化一下。
考虑用一个 map 存在当前 \(f_{i, j}\not = +\infty\) 的 \(j\) 和 \(f_{i, j}\)。
那么对于第一种转移什么都不会发生,对于第二种转移,直接暴力删除区间内的点向 \(f_{i, b_i + 1}\) 更新即可。
同时需要一个 multiset 存下不为 \(+ \infty\) 的 \(f_{i, j}\) 以查找最小值。

时间复杂度分析考虑均摊,最多删去 \(H + W\) 个点,复杂度 \(\mathcal{O}((H + W)\log W)\)。

#include<bits/stdc++.h>
int main() {
   int H, W;
   scanf("%d%d", &H, &W);
   std::map<int, int> S;
   std::multiset<int> D;
   for (int i = 1; i <= W; i++) S[i] = 0, D.insert(0);
   for (int i = 1; i <= H; i++) {
      int a, b; scanf("%d%d", &a, &b);
      auto it = S.lower_bound(a);
      int mn = 1e9, w;
      while (it != S.end() && (w = (*it).first) <= b) {
         mn = std::min(mn, b + 1 - w + (*it).second);
         D.erase(D.find((*it).second)), S.erase(it++);
      }
      if (b < W && mn < (int)1e9) {
         if (S.find(b + 1) != S.end()) {
            D.erase(D.find(S[b + 1]));
            D.insert(S[b + 1] = std::min(S[b + 1], mn));
         } else {
            D.insert(S[b + 1] = mn);
         }
      }
      printf("%d\n", D.empty() ? -1 : ((*D.begin()) + i));
   } 
   return 0;
}

标签:Atcoder,infty,int,Solution,ABC177F,考虑,hate,转移
From: https://www.cnblogs.com/rizynvu/p/18292750

相关文章

  • Solution - Atcoder ARC150D Removing Gacha
    考虑到每次操作都比定会选上一个点,于是答案可以表示为每个点被选中的次数之和。即令\(c_i\)为\(i\)点被选中的次数,答案即为\(E(\sum\limits_{i=1}^nc_i)\)。根据期望的线性性,考虑把答案的\(E\)拆到每个\(c_i\)上,即变为\(\sum\limits_{i=1}^nE(c_i)\)的形式。......
  • Denso Create Programming Contest 2024(AtCoder Beginner Contest 361)E-F
    E求一条树上的路径,使得走遍整棵树花费最小。我们容易发现树上的某条简单路径只需走一次,除此之外所有的路径都需要走两次,那么显而易见,我们需要求树的直径,之后将剩余的路径权值和乘二加上直径权值就可以。F数学题,对于数学题而言,个人感觉时间复杂度的计算对于题目的求解非常重......
  • AtCoder Beginner Contest 361
    AtCoderBeginnerContest361A-Insert给定一个长度为\(N\)的序列\(A\),现在希望将数字\(X\)插入到序列的第\(K\)个数字后面,变成一个新的序列\(B\)。输出序列\(B\)。\(K,N,A_i,X\le100\)模拟题。先读入\(N,K,X\)。接着在读入\(A\)的过程中一遍读入一遍输出,如果读到了第\(K......
  • AtCoder Beginner Contest 361)
    推荐个C++编程仓库模板https://github.com/yxc-s/programming-templateA-Insertvoidsolve(){ intn,k,x; cin>>n>>k>>x; vector<int>a(n); for(auto&x:a){ cin>>x; } a.insert(a.begin()+k,x); for(inti=0;......
  • Denso Create Programming Contest 2024(AtCoder Beginner Contest 361)
    DensoCreateProgrammingContest2024(AtCoderBeginnerContest361)\(A\)Insert\(AC\)循环结构。点击查看代码inta[200];intmain(){intn,k,x,i;cin>>n>>k>>x;for(i=1;i<=n;i++){cin>>a[i];cout......
  • AtCoder Beginner Contest 361 补题记录(A~F)
    开题顺序:A-C-F-D-B-E。A直接模拟即可。boolbegmem;#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;classFastIO{public:intread(){into=1,x;charch;while(!isdigit(ch=getchar())){if......
  • Solution - Atcoder ARC125E Snack
    观察到这种都是数量上限的限制,且求\(\max\)。所以可以考虑网络流建模,而流量就对应着给的糖果数。令\(S\)为源点,\(T\)为汇点,编号为\(1\simn\)的点对应的糖果的种类,编号为\(n+1\simn+m\)的点对应的小孩。连边\((S,i,a_i)\),表示第\(i\)种糖果数不超过\(a_i\)......
  • AtCoder Beginner Contest 359
    AtCoderBeginnerContest359A-CountTakahashi有\(n\)个字符串,每个串要么是Takahashi要么是Aoki,问有多少个字符串是Takahashi额....这还要有题解吗(?)#include<iostream>#include<cstring>usingnamespacestd;intmain(){stringa;intn,ans=0;cin>......
  • Solution - Atcoder AGC010E Rearranging
    因为只有相邻的互质的\(a_i\)可以交换,那么就说明不互质的\(a_i\)无法相交换,对应的位置关系也就不会改变。于是可以考虑图论建模,对于\(\gcd(a_i,a_j)>1\),连边\((i,j)\)。那么对于先手,就相当于要把这些边定向,变为一个DAG。而后手因为要保证最大,所以肯定是在DAG上跑......
  • AtCoder Beginner Contest 359
    AtCoderBeginnerContest359这场我赛时打的非常不好,只做出了\(2\)题。A-CountTakahashi签到//Problem:A-CountTakahashi//Contest:AtCoder-UNIQUEVISIONProgrammingContest2024Summer(AtCoderBeginnerContest359)//URL:https://atcoder.jp/conte......