Submission #204158

# Submission time Handle Problem Language Result Execution time Memory
204158 2020-02-24T17:30:08 Z jond98i Detecting Molecules (IOI16_molecules) C++14
Compilation error
0 ms 0 KB
/*
 * Solution to IOI 2009 problem "raisins"
 *
 * This solution employs memoization in order to compute the the best
 * way of cutting any sub-rectangle of the chocolate. To do this
 * sufficiently quickly, we also precompute the number of raisins in
 * each sub-rectangle subtended from the top-left corner of the chocolate.
 *
 * This allows us to compute the number of raisins in any rectangular
 * sub-region of the chocolate -- consider the diagram below:
 *
 * (0,0)-------+-------(c,0)
 *   |    A    |    B    |
 *   +-------(a,b)-------+
 *   |    C    |    D    |
 * (0,d)-------+-------(c,d)
 *
 * Suppose we wish to compute the number of raisins in the region
 * (a,b) -> (c,d), D. Now D = (A + B + C + D) - (A + B) - (A + C) + A
 * Each of these four quantities is given by the number of raisins
 * in a rectangular sub-region whose top-left corner is (0,0).
 *
 * Carl Hultquist, [email protected]
 */

#include <iostream>
#include <cassert>
#include <climits>
#include <cstring>

using namespace std;

#define MAX_SIZE 50
#define MAX_VAL 1000

// The dimensions of the chocolate
int r, c;

// The number of raisins on each piece of chocolate
short chocolate[MAX_SIZE][MAX_SIZE];

// The number of raisins in a rectangular sub-region subtended from the
// top-left corner of the chocolate.
int raisins[MAX_SIZE][MAX_SIZE];

// The minimum payment that Bonny must make for Peter to cut any
// rectangular sub-region of the chocolate.
int best[MAX_SIZE][MAX_SIZE][MAX_SIZE][MAX_SIZE];

/**
 * Computes the smallest cost of cutting up the rectangular portion of
 * the chocolate from (r1,c1) to (r2,c2).
 */
int solve(int r1, int c1, int r2, int c2)
{
    if (best[r1][c1][r2][c2] == -1)
    {
        // We haven't computed this previously, so compute it now.

        if (r1 == r2 && c1 == c2) {
            // If we have a single cell left, then we're done:
            // there's no additional cost.
            best[r1][c1][r2][c2] = 0;
        }
        else {
            // We try all the possible cuts, and see which results in
            // the smallest total payment.

            int best_payment = INT_MAX;

            // First try the rows
            for (int r = r1 + 1; r <= r2; r++)
            {
                int payment = solve(r1, c1, r - 1, c2) + solve(r, c1, r2, c2);
                if (payment < best_payment)
                    best_payment = payment;
            }

            // Now try the columns
            for (int c = c1 + 1; c <= c2; c++)
            {
                int payment = solve(r1, c1, r2, c - 1) + solve(r1, c, r2, c2);
                if (payment < best_payment)
                    best_payment = payment;
            }

            // Determine how many raisins
            int base_raisins = raisins[r2][c2];
            if (r1 > 0)
                base_raisins -= raisins[r1 - 1][c2];
            if (c1 > 0)
                base_raisins -= raisins[r2][c1 - 1];
            if (r1 > 0 && c1 > 0)
                base_raisins += raisins[r1 - 1][c1 - 1];

            best[r1][c1][r2][c2] = best_payment + base_raisins;
        }
    }

    return best[r1][c1][r2][c2];
}

int main()
{
    cin >> r >> c;
    assert(1 <= r && r <= MAX_SIZE);
    assert(1 <= c && c <= MAX_SIZE);

    // Read in the number of raisins on each piece of chocolate
    for (int i = 0; i < r; i++)
        for (int j = 0; j < c; j++)
        {
            cin >> chocolate[i][j];
            assert(0 <= chocolate[i][j] && chocolate[i][j] <= MAX_VAL);
        }

    memset(raisins, -1, sizeof(raisins));
    memset(best, -1, sizeof(best));

    // First precompute the number of raisins on each rectangular
    // sub-region subtended from the top-left corner of the chocolate.
    raisins[0][0] = chocolate[0][0];

    for (int i = 1; i < r; i++)
        raisins[i][0] = chocolate[i][0] + raisins[i - 1][0];

    for (int j = 1; j < c; j++)
    {
        raisins[0][j] = chocolate[0][j] + raisins[0][j - 1];

        for (int i = 1; i < r; i++)
            raisins[i][j] = chocolate[i][j] + raisins[i - 1][j] + raisins[i][j - 1] - raisins[i - 1][j - 1];
    }

    // Find the minimum payment for cutting up the whole slab of
    // chocolate.
    cout << solve(0, 0, r - 1, c - 1) << endl;

    return 0;
}

Compilation message

/tmp/ccjf11Hl.o: In function `main':
grader.cpp:(.text.startup+0x0): multiple definition of `main'
/tmp/ccYmeWIN.o:molecules.cpp:(.text.startup+0x0): first defined here
/tmp/ccjf11Hl.o: In function `main':
grader.cpp:(.text.startup+0x152): undefined reference to `find_subset(int, int, std::vector<int, std::allocator<int> >)'
collect2: error: ld returned 1 exit status