zoukankan      html  css  js  c++  java
  • topcoder srm 580 div1

    problem1 link

    最优选择一定是在$2n$个端点中选出两个。

    problem2 link

    分开考虑每个区间。设所有区间的左端点的最大值为$lc$,所有区间的右端点的最小值为$rc$.对于某个区间$L$,其实就是找最少的区间(包括$L$)能够完全覆盖区间$[lc,rc]$.

    设$L$的左右端点为$L_{1},L_{2}$。考虑从$L_{1}$向左扩展,每次扩展一定是找一个区间$p$满足$p_{2}geq L_{1}$且使得$p_{1}$最小。右端点向右扩展类似。

    problem3 link

    对于后手来说,它一定是每次只放置一个障碍格子在先手目前的位置。否则,如果放置了太多,那么先手就容易决策出向左还是向右比较好。

    对于先手来说,假设目前先手在$(r,c)$,那么如果$(r,c)$和$(r+1,c)$之间没有障碍,且轮到先手,应该直接跳到$(r+1,c)$,否则,那么由后手的策略来看,此时已经有的障碍一定是一个包含$(r,c)$的区间,此时先手可以尝试向左或者向右运动到障碍区间外一个格子。

    这样就可以用$(r,c,left,right,tag)$来表示一个状态来进行动态规划。$(r,c)$表示先手目前的位置,$(left, right)$表示目前障碍的区间,$tag$指示目前是先手还是后手。

    code for problem1

    #include <vector>
    
    class EelAndRabbit {
     public:
      int getmax(std::vector<int> &l, std::vector<int> t) {
        const int n = static_cast<int>(l.size());
        int ans = 0;
        for (int i = 0; i < n; ++i) {
          for (int j = 0; j < 2; ++j) {
            int p1 = j == 0 ? -t[i] : -t[i] - l[i];
            for (int k = 0; k < n; ++k) {
              for (int r = 0; r < 2; ++r) {
                int p2 = r == 0 ? -t[k] : -t[k] - l[k];
                if (p1 != p2) {
                  int num = 0;
                  long long mask = 0;
                  for (int x = 0; x < n; ++x) {
                    if ((-t[x] - l[x] <= p1 && p1 <= -t[x]) ||
                        (-t[x] - l[x] <= p2 && p2 <= -t[x])) {
                      if ((mask & (1ll << x)) == 0) {
                        ++num;
                        mask |= 1ll << x;
                      }
                    }
                  }
                  ans = std::max(ans, num);
                }
              }
            }
          }
        }
        return ans;
      }
    };

    code for problem2

    #include <algorithm>
    #include <string>
    #include <vector>
    
    constexpr int N = 2500;
    constexpr int M = 10000;
    
    int s[N], t[N];
    int back[M], next[M];
    int back_cost[M], next_cost[M];
    int sort_idx[N];
    
    class ShoutterDiv1 {
     public:
      int count(const std::vector<std::string>& s1000,
                const std::vector<std::string>& s100,
                const std::vector<std::string>& s10,
                const std::vector<std::string>& s1,
                const std::vector<std::string>& t1000,
                const std::vector<std::string>& t100,
                const std::vector<std::string>& t10,
                const std::vector<std::string>& t1) {
        int n = 0;
        for (const auto& e : s1000) {
          n += static_cast<int>(e.size());
        }
        for (int i = 0; i < n; ++i) {
          s[i] = t[i] = 0;
          sort_idx[i] = i;
        }
        for (int i = 0; i < M; ++i) {
          back[i] = next[i] = i;
        }
        Parse(s1000, s, 1000);
        Parse(s100, s, 100);
        Parse(s10, s, 10);
        Parse(s1, s, 1);
        Parse(t1000, t, 1000);
        Parse(t100, t, 100);
        Parse(t10, t, 10);
        Parse(t1, t, 1);
    
        int c_left = t[0];
        int c_right = s[0];
        for (int i = 0; i < n; ++i) {
          back[t[i]] = std::min(back[t[i]], s[i]);
          next[s[i]] = std::max(next[s[i]], t[i]);
          c_left = std::min(c_left, t[i]);
          c_right = std::max(c_right, s[i]);
        }
        for (int i = M - 2; i >= 0; --i) {
          back[i] = std::min(back[i], back[i + 1]);
        }
        for (int i = 1; i < M; ++i) {
          next[i] = std::max(next[i], next[i - 1]);
        }
        for (int i = 0; i < M; ++i) {
          if (i <= c_left) {
            back_cost[i] = 0;
          } else if (i == back[i]) {
            back_cost[i] = -1;
          } else {
            if (back_cost[back[i]] == -1) {
              back_cost[i] = -1;
            } else {
              back_cost[i] = 1 + back_cost[back[i]];
            }
          }
        }
        for (int i = M - 1; i >= 0; --i) {
          if (i >= c_right) {
            next_cost[i] = 0;
          } else if (i == next[i]) {
            next_cost[i] = -1;
          } else {
            if (next_cost[next[i]] == -1) {
              next_cost[i] = -1;
            } else {
              next_cost[i] = 1 + next_cost[next[i]];
            }
          }
        }
        auto Cost = [&](int left, int right) {
          if (back_cost[left] == -1 || next_cost[right] == -1) {
            return -1;
          }
          return back_cost[left] + next_cost[right];
        };
    
        std::sort(sort_idx, sort_idx + n, [&](int x, int y) {
          return s[x] < s[y] || (s[x] == s[y] && t[x] < t[y]);
        });
    
        int result = 0;
        for (int i = 0; i < n; ++i) {
          int tmp = Cost(s[sort_idx[i]], t[sort_idx[i]]);
          for (int j = 0; j < N && s[sort_idx[j]] <= s[sort_idx[i]]; ++j) {
            if (t[sort_idx[i]] <= t[sort_idx[j]]) {
              int val = Cost(s[sort_idx[j]], t[sort_idx[j]]);
              if (val != -1 && (tmp == -1 || tmp > 1 + val)) {
                tmp = 1 + val;
              }
            }
          }
          if (tmp == -1) {
            return -1;
          }
          result += tmp;
        }
        return result;
      }
    
     private:
      void Parse(const std::vector<std::string>& d, int* data, int base) {
        int idx = 0;
        for (size_t i = 0; i < d.size(); ++i) {
          for (size_t j = 0; j < d[i].size(); ++j) {
            data[idx++] += (d[i][j] - '0') * base;
          }
        }
      }
    };

    code for problem3

    #include <cstring>
    #include <limits>
    #include <string>
    #include <vector>
    
    #include <iostream>
    
    constexpr int N = 50;
    constexpr int kEachUseBit = 16;
    constexpr int kRabbitTagBit = 31;
    constexpr int kEelTagBit = 15;
    constexpr int kMask = (1 << (kEachUseBit - 1)) - 1;
    
    using TType = unsigned int;
    
    TType rabbit_eel[N][N][N][N + 1];
    int cost[N][N];
    int h, w;
    
    class WallGameDiv1 {
     public:
      int play(const std::vector<std::string> &costs) {
        h = static_cast<int>(costs.size());
        w = static_cast<int>(costs[0].size());
        for (int i = 0; i < h; ++i) {
          cost[i][0] = costs[i][0] - '0';
          for (int j = 1; j < w; ++j) {
            cost[i][j] = cost[i][j - 1] + costs[i][j] - '0';
          }
        }
    
        memset(rabbit_eel, 0, sizeof(rabbit_eel));
        // Iterator each row to avoid more depths of recursion.
        for (int i = h - 1; i >= 0; --i) {
          for (int j = 0; j < w; ++j) {
            Eel(i, j, j, j);
          }
        }
        int result = std::numeric_limits<int>::max();
        for (int i = 0; i < w; ++i) {
          result = std::min(result, Cost(0, i, i) + Eel(0, i, i, i));
        }
        return result;
      }
    
     private:
      bool Computed(const TType &val, bool is_rabbit) {
        if (is_rabbit) {
          return (val & (1u << kRabbitTagBit)) != 0;
        } else {
          return (val & (1u << kEelTagBit)) != 0;
        }
      }
    
      int GetCost(const TType &val, bool is_rabbit) {
        if (!Computed(val, is_rabbit)) {
          return -1;
        }
        if (is_rabbit) {
          return static_cast<int>((val >> kEachUseBit) & kMask);
        } else {
          return static_cast<int>(val & kMask);
        }
      }
    
      int SetCost(TType &val, bool is_rabbit, int cost) {
        if (is_rabbit) {
          val |= (static_cast<TType>(cost)) << kEachUseBit;
          val |= 1u << kRabbitTagBit;
        } else {
          val |= cost;
          val |= 1u << kEelTagBit;
        }
        return cost;
      }
    
      int Eel(int row, int col, int left, int right) {
        TType &val = rabbit_eel[row][col][left][right];
        int result = GetCost(val, false);
        if (result != -1) {
          return result;
        }
        if (row == h - 1) {
          return SetCost(val, false, 0);
        }
        result = Rabbit(row, col, left, right);
    
        if (right - left < w - 1) {
          result = std::max(result, Rabbit(row, col, std::min(col, left),
                                           std::max(col + 1, right)));
        }
    
        return SetCost(val, false, result);
      }
    
      int Rabbit(int row, int col, int left, int right) {
        TType &val = rabbit_eel[row][col][left][right];
        int result = GetCost(val, true);
        if (result != -1) {
          return result;
        }
        if ((left <= col) && (col < right)) {
          result = std::numeric_limits<int>::max();
          if (left > 0) {
            result = Cost(row, left - 1, col - 1) + Eel(row, left - 1, left, right);
          }
          if (right < w) {
            result = std::min(
                result, Cost(row, col + 1, right) + Eel(row, right, left, right));
          }
        } else {
          result = Cost(row + 1, col, col) + Eel(row + 1, col, col, col);
        }
        return SetCost(val, true, result);
      }
    
      int Cost(int row, int left, int right) {
        if (left <= right) {
          if (left == 0) {
            return cost[row][right];
          }
          return cost[row][right] - cost[row][left - 1];
        }
        return 0;
      }
    };
  • 相关阅读:
    html5--4-1 video/视频播放
    html5--3.22 综合实例03
    html5--3.21 课程小结与其他新增元素
    html5--3.20 新增的keygen元素
    UVA11324-- The Largest Clique(SCC+DP)
    memset函数具体说明
    XMPP协议的原理介绍
    探索WebKit内核(一)------ 菜鸟起步
    图像切割之(一)概述
    LeetCode——Count and Say
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/9250256.html
Copyright © 2011-2022 走看看