# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
631854 | rainliofficial | Aliens (IOI16_aliens) | C++14 | 0 ms | 0 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "aliens.h"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
typedef pair<int, int> pii;
template<class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
#define sz(x) (int)x.size()
const int MAXN = 2e5+5, INF = 1e9;
struct Point{
int r, c, id, cnt;
bool operator<(const Point& o) const{
if (r != o.r){
return r < o.r;
}
return c < o.c;
}
};
bool byr(const Point& a, const Point& b){
return a.r != b.r ? a.r < b.r : a.c > b.c; // sort by smaller row, then by greater col
}
bool byc(const Point& a, const Point& b){
return a.c != b.c ? a.c < b.c : a.r > b.r; // smaller col, smaller row
}
int getArea(Point a, Point b, Point pv){
int area = (b.c - a.r + 1)*(b.c - a.r + 1);
if (pv.c == -1) return area;
int overlap = pv.c - a.r + 1;
if (overlap <= 0){
return area;
}else{
return area - overlap*overlap;
}
}
long long take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c) {
// reflect the points under the diag
vector<Point> arr;
int tot = 0;
set<Point> allPoints;
for (int i=0; i<n; i++){
if (r[i] > c[i]){
swap(r[i], c[i]);
}
Point cur = {r[i], c[i], tot, 1};
auto it = allPoints.find(cur);
if (it != allPoints.end()){
arr[(*it).id].cnt++;
}else{
arr.push_back(cur);
allPoints.insert(cur);
tot++;
}
}
n = tot;
sort(arr.begin(), arr.end(), byr);
set<Point, decltype(&byc)> seen(&byc);
for (int i=0; i<n; i++){
auto it = seen.lower_bound(arr[i]);
if (it == seen.end()){
seen.insert(arr[i]);
}else{
// Point upd = *it;
// upd.cnt++;
// seen.erase(it);
// seen.insert(upd);
}
}
arr.clear();
for (Point x : seen){
// cout << x.r << " " << x.c << " " << x.id << " " << x.cnt << "\n";
arr.push_back(x);
}
n = sz(arr);
// run dp
vector<vector<int>> dp(n+1, vector<int>(k+1, INF)); // dp[i][j] = max cover up to ith point after taking j pictures
for (int i=0; i<=k; i++) dp[0][i] = 0;
for (int i=1; i<=n; i++){
for (int j=1; j<=k; j++){
for (int ip=1; ip<=i; ip++){
if (ip > 1){
ckmin(dp[i][j], dp[ip-1][j-1] + getArea(arr[ip-1], arr[i-1], arr[ip-2]));
}else{
ckmin(dp[i][j], dp[ip-1][j-1] + getArea(arr[ip-1], arr[i-1], {-1, -1, -1, -1}));
}
}
}
}
return dp[n][k];
}