Решить задачу "Паркет". Найти количество способов замостить эту площадь фигурами - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте! Нужна помощь, нужно решить олимпиадную задачку по динамическому программированию по профилю на С#. Обшарил весь нет, нашел реализацию на с++ на русскоязычных сайтах, на англоязычных никакой информации по программированию по профилю нету. С с++ никогда не имел дело, а с# только осваиваю, с динамикой не сталкивался... Может кто-то писал алгоритм на sharpe, а то на с++ разобраться не получается. Вот такое объяснение и реализацию на с++ нашел в Интернете: Задача "Паркет" Имеется прямоугольная площадь размером NxM. Нужно найти количество способов замостить эту площадь фигурами 1x2 (пустых клеток не должно оставаться, фигуры не должны накладываться друг на друга). Построим такую динамику: D[I][Mask], где I=1..N, Mask=0..2^M-1. I обозначает количество строк в текущем поле, а Mask - профиль последней строки в текущем поле. Если j-й бит в Mask равен нулю, то в этом месте профиль проходит на "нормальном уровне", а если 1 - то здесь "выемка" глубиной 1. Ответом, очевидно, будет D[N][0]. Строить такую динамику будем, просто перебирая все I=1..N, все маски Mask=0..2^M-1, и для каждой маски будем делать переходы вперёд, т.е. добавлять к ней новую фигуру всеми возможными способами. Реализация:
int n, m;
vector < vector<long long> > d;
void calc (int x = 0, int y = 0, int mask = 0, int next_mask = 0)
{
if (x == n)
return;
if (y >= m)
d[x+1][next_mask] += d[x][mask];
else
{
int my_mask = 1 << y;
if (mask & my_mask)
calc (x, y+1, mask, next_mask);
else
{
calc (x, y+1, mask, next_mask | my_mask);
if (y+1 < m && ! (mask & my_mask) && ! (mask &
(my_mask << 1)))
calc (x, y+2, mask, next_mask);
}
}
}
int main()
{
cin >> n >> m;
d.resize (n+1, vector<long long> (1<<m));
d[0][0] = 1;
for (int x=0; x<n; ++x)
for (int mask=0; mask<(1<<m); ++mask)
calc (x, 0, mask, 0);
cout << d[n][0];
}

Решение задачи: «Решить задачу "Паркет". Найти количество способов замостить эту площадь фигурами»

textual
Листинг программы
class Program
    {
        static int height, width;
        static long[,] array;
 
        static void Main(string[] args)
        {
            
            Console.Write("Input height: ");
            height = Convert.ToInt32(Console.ReadLine());
 
            Console.Write("Input width: ");
            width = Convert.ToInt32(Console.ReadLine());
 
            array = new long[height, width];
            array[0,0] = 1;
            for (int x = 0; x < height; ++x)
                for (int mask = 0; mask < (1 << width); ++mask)
                    calc (x, 0, mask, 0);
            Console.Write(array[height, 0]);
            Console.ReadKey();
        }
 
        static void calc(int x = 0, int y = 0, int mask = 0, int next_mask = 0)
        {
            if (x == height) return;
            if (y >= width)
                array[x + 1, next_mask] += array[x, mask];
            else
            {
                int my_mask = 1 << y;
                if (mask & my_mask)
                    calc(x, y + 1, mask, next_mask);
                else
                {
                    calc(x, y + 1, mask, next_mask | my_mask);
                    if (y + 1 < width && !(mask & my_mask) && !(mask & (my_mask << 1)))
                        calc(x, y + 2, mask, next_mask);
                }
            }
        }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 3.8 из 5
Похожие ответы