Заполнение комнаты 2*n двумя разными тайлами

Я столкнулся с проблемой, когда мне нужно заполнить прямоугольник, имеющий 2 строки и n столбцов. Есть две плитки: одна плитка 1 * 2, а вторая плитка L-образной формы с большими сторонами, имеющими размерность 2 единицы, и меньшими сторонами, имеющими размерность 1 единицу.

Я решил это с помощью динамического программирования и не совсем уверен, работает ли он нормально или нет. Если нет, то какой будет правильный восходящий код этой проблемы. Ниже приведен фрагмент функции моего решения.

Для повторения один столбец можно заполнить одним способом, положив первый тайл вертикально, два соседних столбца можно заполнить одним способом, положив первый тип тайла горизонтально один за другим. Три соседних столбца можно заполнить, выровняв две L-образные в перевернутом виде двумя способами, а четыре соседних столбца можно заполнить двумя L-образными плитками, обращенными друг к другу, и плиткой первого типа, лежащей горизонтально, двумя способами.

int tileways(int n) //n=no.of columns of the rectangle.
{
    int i;
    int a[n+4];
    a[0]=0;
    a[1]=0;
    a[2]=0;
    a[3]=1;
    for(i=4;i<n+4;i++)
    {
        a[i]=a[i-1]+a[i-2]+2*a[i-3]+2*a[i-4];
    }
    return a[n+3];
}

person soumyadip_poddar    schedule 30.01.2021    source источник
comment
Вы не объяснили это повторение. Я думаю, что можно было бы решить ДП, используя три правые конфигурации: |, L, Г или две | + 2*L из-за симметрии   -  person MBo    schedule 30.01.2021
comment
@MBo отредактировано. Спасибо.   -  person soumyadip_poddar    schedule 30.01.2021
comment
C++ не поддерживает массивы динамической длины, это поддерживают только некоторые компиляторы, поэтому рассмотрим здесь std::vector.   -  person tadman    schedule 30.01.2021
comment
Мне кажется, что a[1] = 1, a[2] = 2, a[3]=5 (|||, |=, =|. два случая LL)   -  person MBo    schedule 30.01.2021
comment
@tadman спасибо. Но я хочу знать, верна ли логика. Или я что-то упускаю?   -  person soumyadip_poddar    schedule 30.01.2021
comment
Трудно сказать, не углубляясь в это значительно больше, о чем много вопросов. Демонстрация кода — хороший первый шаг. Также важно показать нам а) как эта функция предназначена для использования с некоторым демонстрационным кодом и б) каков ваш ожидаемый результат и что именно не так с выходом этого кода.   -  person tadman    schedule 30.01.2021
comment
@MBo Я сдвинул массив, и то, что вы думаете о [3], ответ на самом деле присутствует в [6], и будет 5, пожалуйста, проверьте [6], я думаю, это будет намного яснее. Я взял a[0], a[1], a[2] и a[3] в качестве базовых случаев, поэтому мой массив сместился на 4 единицы.   -  person soumyadip_poddar    schedule 30.01.2021
comment
@tadman да, я знаю это :-( Я бы не стал спрашивать, присутствует ли этот вопрос на других платформах кодирования. Я видел его в блоге, но не было компилятора, чтобы проверить правильность моего ответа. Скорее, я проверяю большинство платформ кодирования и не может найти вопрос.   -  person soumyadip_poddar    schedule 30.01.2021
comment
Мой совет — разбить эту проблему на части и написать модульные тесты с помощью такого инструмента, как Catch2, чтобы убедиться, что у вас есть правильная реализация. Предоставьте ему варианты использования, начиная с самых простых и заканчивая более сложными, и посмотрите, как он работает.   -  person tadman    schedule 30.01.2021
comment
Хорошо, теперь ясно. Но ваш код дает последовательность, не представленную в OEIS, поэтому, возможно, это неправильно.   -  person MBo    schedule 30.01.2021
comment
Правый: oeis.org/A052980 1, 2, 5, 11, 24, 53, 117, 258.   -  person MBo    schedule 30.01.2021
comment
@MBo ооо, тогда, может быть, неправильно. Я этого не знал.   -  person soumyadip_poddar    schedule 30.01.2021


Ответы (1)


Используя подход из моего первого комментария.

l[3] конфигурация:

введите здесь описание изображения

L[3] конфигурации:

введите здесь описание изображения введите здесь описание изображения

#include <iostream>
using namespace std;

int tileways(int n) //n=no.of columns of the rectangle.
{
    int l[20];//straight border
    int L[20];//extra square
    l[0] = 1; 
    l[1] = 1;
    L[0] = 0;
    L[1] = 1;
    for (int i = 2; i <=n; i++) {

        l[i] = l[i-1] + l[i-2] + 2*L[i-2]; 
        //add | to the last straight, = to the 2nd last straight, 
        //two cases of L to extra

        L[i] = l[i-1] + L[i-1];
        //add L to the last straight, - to the extra 
    }
    return l[n];
}

int main() {
    for (int i = 1; i < 10; i++) 
        std::cout<<i<<" "<< tileways(i)<<std::endl;
    return 0;
}

Результат ideone

1 1
2 2
3 5
4 11
5 24
6 53
7 117
8 258
9 569

Для справки: последовательность OEIS number of possible tilings of a 2 X n board, using dominos and L-shaped trominos.

1, 2, 5, 11, 24, 53, 117, 258
person MBo    schedule 30.01.2021
comment
Что именно представляет массив L? Я не могу этого понять. - person soumyadip_poddar; 30.01.2021
comment
количество конфигураций с заполненной длиной i и зубчатым концом (дополнительный квадрат из L-образной формы или горизонтальная полоса на конце) - person MBo; 30.01.2021
comment
L[1] равно 1. Почему 1 столбец может быть заполнен 1 тромино? - person soumyadip_poddar; 30.01.2021
comment
Первый столбец заполнен, второй содержит один квадрат - person MBo; 30.01.2021
comment
@ но разве это не незаконно, поскольку мы считаем, что ни один столбец не может быть заполнен наполовину или нет?? Например, дополнительная часть переходит в следующий столбец, что нарушает dp, делая следующий столбец заполненным наполовину. - person soumyadip_poddar; 30.01.2021
comment
Все столбцы до i-го заполнены полностью. Если (i+1)-й столбец еще не содержит квадратов, вариант засчитывается в l[], если он содержит один лишний квадрат - - вариант засчитывается в L[] - person MBo; 30.01.2021