Submission #764214

#TimeUsernameProblemLanguageResultExecution timeMemory
764214mousebeaverAliens (IOI16_aliens)C++14
60 / 100
398 ms62900 KiB
#include "aliens.h"
#include <bits/stdc++.h>
#define ll long long
#define INF numeric_limits<ll>::max()/2
#define pll pair<ll, ll>
using namespace std;

ll cost(ll i, ll j, vector<pll>& a)
{
    ll root = a[j-1].second - a[i-1].first+1;
    ll area = root*root; //Area of the necessary square to cover the given cells
    if(i > 1 && a[i-1].first <= a[i-2].second)
    {
        //Calculate the overlap with the previous square
        root = a[i-2].second-a[i-1].first+1;
        area -= root*root;
    }
    return area;
}

void calc(vector<vector<ll>>& dp, ll j, ll left, ll right, ll optl, ll optr, vector<pll>& a)
{
    if(left > right)
    {
        return;
    }

    ll mid = (left+right)/2;
    ll opt = -1;
    for(ll b = optl; b <= min(optr, mid); b++)
    {
        ll val = dp[b-1][j-1]+cost(b, mid, a);

        if(val < dp[mid][j])
        {
            dp[mid][j] = val;
            opt = b;
        }
    }
    dp[mid][j] = min(dp[mid][j], dp[mid][j-1]);

    calc(dp, j, left, mid-1, optl, opt, a);
    calc(dp, j, mid+1, right, opt, optr, a);
}

long long take_photos(int n, int m, int k, std::vector<int> r, std::vector<int> c)
{
    vector<pll> a(n);
    for(ll i = 0; i < n; i++)
    {
        a[i] = {r[i], c[i]};
        if(c[i] < r[i]) //Mirror to diagonal or above
        {
            swap(a[i].first, a[i].second);
        }
    }

    sort(a.begin(), a.end());
    vector<pll> b(0);
    for(ll i = 0; i < n; i++)
    {
        if((i == n-1 || a[i].first != a[i+1].first) && (b.empty() || a[i].second > b.back().second))
        {
            b.push_back(a[i]);
        }
    }
    a = b;
    n = a.size();
    k = min(k, n);

    if(n <= 500)
    {
        vector<vector<ll>> dp(n+1, vector<ll> (k+1, INF));
        dp[0][0] = 0;
        for(ll i = 1; i <= n; i++)
        {
            for(ll j = 1; j <= k; j++)
            {
                dp[i][j] = dp[i][j-1];
                for(ll b = 1; b <= i; b++)
                {
                    ll val = dp[b-1][j-1]+cost(b, i, a);
                    dp[i][j] = min(dp[i][j], val);
                }
            }
        }

        return dp[n][k];
    }

    if(n <= 4000 || k <= 100)
    {
        vector<vector<ll>> dp(n+1, vector<ll> (k+1, INF));
        dp[0][0] = 0;

        for(ll j = 1; j <= k; j++)
        {
            calc(dp, j, j, n, 1, n, a);
        }

        return dp[n][k];
    }

    return 0;
}
#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...