Submission #429145

#TimeUsernameProblemLanguageResultExecution timeMemory
429145JeanBombeurAliens (IOI16_aliens)C++17
41 / 100
1060 ms501588 KiB
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> #include "aliens.h" using namespace std; // <|°_°|> const long long INFINI = (1LL << 60); const int MAX_POINTS = (4001); const int LOG = (40); struct droite { long long pente, cst; int prix; }; long long DP[MAX_POINTS][MAX_POINTS]; pair <long long, long long> Points[MAX_POINTS]; pair <int, int> Aliens[MAX_POINTS]; droite Deque[MAX_POINTS][MAX_POINTS]; int deb[MAX_POINTS]; int fin[MAX_POINTS]; int nbPoints = 0; bool Compare(pair <int, int> a, pair <int, int> b) { if (a.first != b.first) return a.first < b.first; return a.second > b.second; } long double Inter(droite a, droite b) { if (a.pente == b.pente) return INFINI; if (a.pente < b.pente) swap(a, b); return (long double)(b.cst - a.cst) / (long double)(a.pente - b.pente); } void Insert(droite a, int id) { while (fin[id] > deb[id] + 1 && Inter(Deque[fin[id] - 2][id], a) <= Inter(Deque[fin[id] - 2][id], Deque[fin[id] - 1][id])) fin[id] --; Deque[fin[id] ++][id] = a; return; } pair <long long, int> GetMin(long long absc, int id) { while (fin[id] > deb[id] + 1 && (long double)absc >= Inter(Deque[deb[id]][id], Deque[deb[id] + 1][id])) deb[id] ++; return {Deque[deb[id]][id].pente * absc + Deque[deb[id]][id].cst, Deque[deb[id]][id].prix}; } // pair <long long, int> FindDP(long long lambda) { // deb = 0, fin = 0; // pair <long long, int> DP = {0LL, 0}; // Insert({- 2 * Points[0].first, Points[0].first * Points[0].first, 0}); // for (int i = 0; i < nbPoints; i ++) // { // DP = GetMin(Points[i].second); // DP.first += Points[i].second * Points[i].second + lambda; // DP.second ++; // if (i + 1 < nbPoints) // { // long long d = max(0LL, Points[i].second - Points[i + 1].first); // Insert({- 2 * Points[i + 1].first, // Points[i + 1].first * Points[i + 1].first - d * d + DP.first, DP.second}); // } // } // return DP; // } void Treat(int noeud) { for (int i = 1; i <= nbPoints; i ++) { DP[noeud][i] = GetMin(Points[noeud].second, i - 1).first + Points[noeud].second * Points[noeud].second; } if (noeud + 1 == nbPoints) return; for (int i = 1; i <= nbPoints; i ++) { long long d = max(0LL, Points[noeud].second - Points[noeud + 1].first); Insert({- 2 * Points[noeud + 1].first, Points[noeud + 1].first * Points[noeud + 1].first - d * d + DP[noeud][i], 0}, i); } return; } void DPDebile() { Insert({- 2 * Points[0].first, Points[0].first * Points[0].first, 0}, 0); for (int i = 0; i < nbPoints; i ++) { Treat(i); } return; } long long take_photos(int nbAliens, int tailleMax, int nbPhotos, vector<int> Lignes, vector<int> Colonnes) { tailleMax ++; for (int i = 0; i < nbAliens; i ++) { if (Lignes[i] > Colonnes[i]) swap(Lignes[i], Colonnes[i]); Aliens[i] = {Lignes[i], Colonnes[i] + 1}; } sort(Aliens, Aliens + nbAliens, Compare); for (int i = 0; i < nbAliens; i ++) { if (nbPoints == 0 || Aliens[i].second > (int)Points[nbPoints - 1].second) Points[nbPoints ++] = Aliens[i]; } DPDebile(); return DP[nbPoints - 1][min(nbPhotos, nbPoints)]; /* long long lambda = -1; long long ans = 0; for (long long i = (1LL << LOG); i > 0; i /= 2) { pair <long long, int> DP = FindDP(lambda + i); if (DP.second <= nbPhotos) ans = DP.first - (lambda + i) * DP.second; else lambda += i; } return ans;*/ }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...