#include <iostream>
#include <vector>
#include <algorithm>
#include <limits>
class ApartmentHunting {
private:
std::vector<std::vector<int>> populateBlocks() {
std::vector<std::vector<int>> blocks = {
{0, 1, 0},
{1, 0, 0},
{1, 1, 0},
{0, 1, 0},
{0, 1, 1}
};
return blocks;
}
std::vector<std::vector<int>> initiateDp(int blocksCount, int reqsCount) {
std::vector<std::vector<int>> dp(blocksCount, std::vector<int>(reqsCount + 1, std::numeric_limits<int>::max()));
return dp;
}
public:
int huntAndGetResult(std::vector<int>& requirements) {
std::vector<std::vector<int>> blocks = populateBlocks();
int blocksCount = blocks.size();
int reqsCount = requirements.size();
int result = std::numeric_limits<int>::max();
std::vector<std::vector<int>> dp = initiateDp(blocksCount, reqsCount);
int AMENITY_UNAVAILABLE = std::numeric_limits<int>::max();
int AMENITY_AVAILABLE = 0;
for (int j = 0; j < reqsCount; j++) {
if (blocks[0][requirements[j]] == 1) {
dp[0][j] = AMENITY_AVAILABLE;
}
}
for (int i = 1; i < blocksCount; i++) {
dp[i][reqsCount] = 0;
for (int j = 0; j < reqsCount; j++) {
if (blocks[i][requirements[j]] == 1) {
dp[i][j] = AMENITY_AVAILABLE;
} else {
if (dp[i - 1][j] != AMENITY_UNAVAILABLE)
dp[i][j] = std::min(dp[i][j], dp[i - 1][j] + 1);
}
dp[i][reqsCount] = std::max(dp[i][reqsCount], dp[i][j]);
}
}
for (int i = blocksCount - 2; i >= 0; i--) {
dp[i][reqsCount] = 0;
for (int j = 0; j < reqsCount; j++) {
if (blocks[i][requirements[j]] == 1) {
dp[i][j] = 0;
} else {
if (dp[i + 1][j] != AMENITY_UNAVAILABLE)
dp[i][j] = std::min(dp[i][j], dp[i + 1][j] + 1);
}
dp[i][reqsCount] = std::max(dp[i][reqsCount], dp[i][j]);
}
result = (dp[i][reqsCount] <= result) ? i : result;
}
return (result + 1);
}
};
int main() {
ApartmentHunting apartmentHunting;
std::vector<int> requirements = {0, 1, 2};
int result = apartmentHunting.huntAndGetResult(requirements);
std::cout << "Block: " << result << " is the answer." << std::endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8bGltaXRzPgoKY2xhc3MgQXBhcnRtZW50SHVudGluZyB7CnByaXZhdGU6CiAgICBzdGQ6OnZlY3RvcjxzdGQ6OnZlY3RvcjxpbnQ+PiBwb3B1bGF0ZUJsb2NrcygpIHsKICAgICAgICBzdGQ6OnZlY3RvcjxzdGQ6OnZlY3RvcjxpbnQ+PiBibG9ja3MgPSB7CiAgICAgICAgICAgIHswLCAxLCAwfSwKICAgICAgICAgICAgezEsIDAsIDB9LAogICAgICAgICAgICB7MSwgMSwgMH0sCiAgICAgICAgICAgIHswLCAxLCAwfSwKICAgICAgICAgICAgezAsIDEsIDF9CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gYmxvY2tzOwogICAgfQoKICAgIHN0ZDo6dmVjdG9yPHN0ZDo6dmVjdG9yPGludD4+IGluaXRpYXRlRHAoaW50IGJsb2Nrc0NvdW50LCBpbnQgcmVxc0NvdW50KSB7CiAgICAgICAgc3RkOjp2ZWN0b3I8c3RkOjp2ZWN0b3I8aW50Pj4gZHAoYmxvY2tzQ291bnQsIHN0ZDo6dmVjdG9yPGludD4ocmVxc0NvdW50ICsgMSwgc3RkOjpudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKSkpOwogICAgICAgIHJldHVybiBkcDsKICAgIH0KCnB1YmxpYzoKICAgIGludCBodW50QW5kR2V0UmVzdWx0KHN0ZDo6dmVjdG9yPGludD4mIHJlcXVpcmVtZW50cykgewogICAgICAgIHN0ZDo6dmVjdG9yPHN0ZDo6dmVjdG9yPGludD4+IGJsb2NrcyA9IHBvcHVsYXRlQmxvY2tzKCk7CiAgICAgICAgaW50IGJsb2Nrc0NvdW50ID0gYmxvY2tzLnNpemUoKTsKICAgICAgICBpbnQgcmVxc0NvdW50ID0gcmVxdWlyZW1lbnRzLnNpemUoKTsKICAgICAgICBpbnQgcmVzdWx0ID0gc3RkOjpudW1lcmljX2xpbWl0czxpbnQ+OjptYXgoKTsKICAgICAgICBzdGQ6OnZlY3RvcjxzdGQ6OnZlY3RvcjxpbnQ+PiBkcCA9IGluaXRpYXRlRHAoYmxvY2tzQ291bnQsIHJlcXNDb3VudCk7CiAgICAgICAgaW50IEFNRU5JVFlfVU5BVkFJTEFCTEUgPSBzdGQ6Om51bWVyaWNfbGltaXRzPGludD46Om1heCgpOwogICAgICAgIGludCBBTUVOSVRZX0FWQUlMQUJMRSA9IDA7CgogICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgcmVxc0NvdW50OyBqKyspIHsKICAgICAgICAgICAgaWYgKGJsb2Nrc1swXVtyZXF1aXJlbWVudHNbal1dID09IDEpIHsKICAgICAgICAgICAgICAgIGRwWzBdW2pdID0gQU1FTklUWV9BVkFJTEFCTEU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgYmxvY2tzQ291bnQ7IGkrKykgewogICAgICAgICAgICBkcFtpXVtyZXFzQ291bnRdID0gMDsKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCByZXFzQ291bnQ7IGorKykgewogICAgICAgICAgICAgICAgaWYgKGJsb2Nrc1tpXVtyZXF1aXJlbWVudHNbal1dID09IDEpIHsKICAgICAgICAgICAgICAgICAgICBkcFtpXVtqXSA9IEFNRU5JVFlfQVZBSUxBQkxFOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZHBbaSAtIDFdW2pdICE9IEFNRU5JVFlfVU5BVkFJTEFCTEUpCiAgICAgICAgICAgICAgICAgICAgICAgIGRwW2ldW2pdID0gc3RkOjptaW4oZHBbaV1bal0sIGRwW2kgLSAxXVtqXSArIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZHBbaV1bcmVxc0NvdW50XSA9IHN0ZDo6bWF4KGRwW2ldW3JlcXNDb3VudF0sIGRwW2ldW2pdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yIChpbnQgaSA9IGJsb2Nrc0NvdW50IC0gMjsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgZHBbaV1bcmVxc0NvdW50XSA9IDA7CiAgICAgICAgICAgIGZvciAoaW50IGogPSAwOyBqIDwgcmVxc0NvdW50OyBqKyspIHsKICAgICAgICAgICAgICAgIGlmIChibG9ja3NbaV1bcmVxdWlyZW1lbnRzW2pdXSA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgZHBbaV1bal0gPSAwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpZiAoZHBbaSArIDFdW2pdICE9IEFNRU5JVFlfVU5BVkFJTEFCTEUpCiAgICAgICAgICAgICAgICAgICAgICAgIGRwW2ldW2pdID0gc3RkOjptaW4oZHBbaV1bal0sIGRwW2kgKyAxXVtqXSArIDEpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZHBbaV1bcmVxc0NvdW50XSA9IHN0ZDo6bWF4KGRwW2ldW3JlcXNDb3VudF0sIGRwW2ldW2pdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXN1bHQgPSAoZHBbaV1bcmVxc0NvdW50XSA8PSByZXN1bHQpID8gaSA6IHJlc3VsdDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIChyZXN1bHQgKyAxKTsKICAgIH0KfTsKCmludCBtYWluKCkgewogICAgQXBhcnRtZW50SHVudGluZyBhcGFydG1lbnRIdW50aW5nOwogICAgc3RkOjp2ZWN0b3I8aW50PiByZXF1aXJlbWVudHMgPSB7MCwgMSwgMn07CiAgICBpbnQgcmVzdWx0ID0gYXBhcnRtZW50SHVudGluZy5odW50QW5kR2V0UmVzdWx0KHJlcXVpcmVtZW50cyk7CiAgICBzdGQ6OmNvdXQgPDwgIkJsb2NrOiAiIDw8IHJlc3VsdCA8PCAiIGlzIHRoZSBhbnN3ZXIuIiA8PCBzdGQ6OmVuZGw7CiAgICByZXR1cm4gMDsKfQo=