topcoder srm 610 div1

problem1 link

 计算每个格子向上的最大高度。然后每个格子同一行前面的格子以及当前格子作为选取的矩形的最后一行,计算面积并更新答案。

problem2 link

对于两个数据$(x_{1},y_{1}),(x_{2},y_{2})$,若先完成第一个再完成第二个,那么一开始的值$F$需要满足$F\geq max(x_{1}, x_{2}+(x_{1}-y_{1}))$,反过来需要满足$F\geq max(x_{2}, x_{1}+(x_{2}-y_{2}))$。所以若前者更优的话,那么有$max(x_{1}, x_{2}+(x_{1}-y_{1}))<max(x_{2}, x_{1}+(x_{2}-y_{2}))$

由于$x_{1}>y_{1}, x_{2}>y_{2}$,所以等价于$y_{1}<y_{2}$。所以按照$y$升序排序,然后从前向后dp即可。

problem3 link

最后最优值跟$x$的函数关系是多个线段,且这些线段是一个凸函数。如下图的棕色线所示。从后向前扩展每个点。每次扩展相当于把之前的折线从最高处垂直分开然后向两边平移一段距离,然后加上当前点的代价。

 

code for problem1

#include <string>
#include <vector>

class TheMatrix {
 public:
  int MaxArea(const std::vector<std::string> &board) {
    int n = static_cast<int>(board.size());
    int m = static_cast<int>(board[0].size());
    std::vector<std::vector<int>> h(n, std::vector<int>(m));
    int result = 0;
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < m; ++j) {
        if (i == 0 || board[i][j] == board[i - 1][j]) {
          h[i][j] = 1;
        } else {
          h[i][j] = h[i - 1][j] + 1;
        }
        result = std::max(result, h[i][j]);
        int min_h = h[i][j];
        for (int k = j - 1; k >= 0 && board[i][k] != board[i][k + 1]; --k) {
          min_h = std::min(min_h, h[i][k]);
          result = std::max(result, min_h * (j - k + 1));
        }
      }
    }
    return result;
  }
};

code for problem2

#include <algorithm>
#include <queue>
#include <vector>

class AlbertoTheAviator {
 public:
  int MaximumFlights(int F, const std::vector<int> &duration,
                     const std::vector<int> &refuel) {
    int n = static_cast<int>(duration.size());
    std::vector<int> indices(n);
    for (int i = 0; i < n; ++i) {
      indices[i] = i;
    }
    std::sort(indices.begin(), indices.end(),
              [&](int l, int r) { return refuel[l] > refuel[r]; });
    std::vector<std::vector<int>> f(n, std::vector<int>(F + 1));
    for (int i = duration[indices[n - 1]]; i <= F; ++i) {
      f[n - 1][i] = 1;
    }
    for (int i = n - 2; i >= 0; --i) {
      for (int j = 1; j <= F; ++j) {
        f[i][j] = f[i + 1][j];
        if (j >= duration[indices[i]]) {
          f[i][j] = std::max(
              f[i][j],
              1 + f[i + 1][j - duration[indices[i]] + refuel[indices[i]]]);
        }
      }
    }
    return f[0][F];
  }
};

code for problem3

import java.math.*;
import java.util.*;

public class MiningGoldHard {
  public int GetMaximumGold(int n, int m, int[] event_i, int[] event_j, int[] event_di, int[] event_dj) {
    return Solve(n, event_i, event_di) + Solve(m, event_j, event_dj);
  }

  int Solve(int N, int[] e, int[] d) {
    int m = e.length;
    List<Point> ends = new ArrayList<Point>();
    ends.add(new Point(0, N - e[m - 1]));
    ends.add(new Point(e[m - 1], N));
    ends.add(new Point(N, e[m - 1]));
    for (int i = m - 2; i >= 0; -- i) {
      List<Point> newEnds = new ArrayList <Point>();
      if (d[i] > 0) {
        int low = 0;
        while (low + 1 < ends.size() && ends.get(low).y < ends.get(low + 1).y) {
          ++low;
        }
        for (int j = 0; j <= low; ++ j) {
          Point p = ends.get(j);
          newEnds.add(new Point(p.x - d[i], p.y));
        }
        for (int j = low; j < ends.size(); ++ j) {
          Point p = ends.get(j);
          newEnds.add(new Point(p.x + d[i], p.y));
        }
        ends = newEnds;
      }
      newEnds = new ArrayList<Point>();
      for (int j = 0; j < ends.size(); ++ j) {
        if ((j + 1 < ends.size() && ends.get(j + 1).x < 0) || (j > 0 && ends.get(j - 1).x > N))  {
          continue;
        }
        Point p = ends.get(j);
        newEnds.add(new Point(p.x, p.y + N - Math.abs(p.x - e[i])));
        if (p.x < e[i] && j + 1 < ends.size() && e[i] < ends.get(j + 1).x) {
          Point q = ends.get(j + 1);
          newEnds.add(new Point(e[i], N + p.y + (q.y - p.y) * (e[i] - p.x) / (q.x - p.x)));
        }
      }
      ends = newEnds;
    }
    int result = 0;;
    for (Point end : ends) {
      if (0 <= end.x && end.x <= N) {
        result = Math.max(result, (int)end.y);
      }
    }
    return result;
  }

  class Point {
    Point(long x, long y) {
      this.x = x;
      this.y = y;
    }
    long x, y;
  }
}

转载于:https://www.cnblogs.com/jianglangcaijin/p/9573041.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值