poj1185

状态压缩dp

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
using namespace std;

#define MAX_COL_NUM 15
#define MAX_ROW_NUM 105
#define MAX_STAT 2050

struct Status
{
    int row_bit[3];
    int last_bit_count;
}status[100000];

int row_num, col_num;
int grid[MAX_ROW_NUM];
int f[3][MAX_STAT][MAX_STAT];
int ans;
int status_cnt;

void input()
{
    scanf("%d%d", &row_num, &col_num);
    for (int i = 0; i < row_num; i++)
    {
        char row[MAX_COL_NUM];
        scanf("%s", row);
        int row_bit = 0;
        for (int j = 0; row[j]; j++)
        {
            if (row[j] == 'H')
            {
                row_bit = (row_bit << 1) | 1;
            }else
            {
                row_bit = (row_bit << 1) | 0;
            }
        }
        grid[i] = row_bit;
    }
}

int count_bit(int a)
{
    int ret = 0;
    while (a > 0)
    {
        if (a & 1)
            ret++;
        a >>= 1;
    }
    return ret;
}

bool ok(int bit)
{
    while (bit > 0)
    {
        if ((bit & 3) == 3)
            return false;
        if ((bit & 5) == 5)
            return false;
        bit >>= 1;
    }
    return true;
}

bool ok(int bit, int row)
{
    return (bit & grid[row]) == 0;
}

void init()
{
    memset(f, 0, sizeof(f));
    int col_stat = 1;
    for (int i = 0; i < col_num; i++)
        col_stat *= 3;
    for (int i = 0; i < col_stat; i++)
    {
        int temp = i;
        int row_bit[3];
        row_bit[1] = row_bit[0] = 0;
        for (int j = 0; j < col_num; j++)
        {
            row_bit[0] <<= 1;
            row_bit[1] <<= 1;
            row_bit[temp % 3] |= 1;
            temp /= 3;
        }
        if (!ok(row_bit[0], 0) || !ok(row_bit[1], 1) || !ok(row_bit[0]) || !ok(row_bit[1]))
        {
            f[0][row_bit[0]][row_bit[1]] = 0;
            continue;
        }
        f[0][row_bit[0]][row_bit[1]] = count_bit(row_bit[0]) + count_bit(row_bit[1]);
        ans = max(ans, f[0][row_bit[0]][row_bit[1]]);
    }    

}

void make_stat()
{
    int col_stat = 1;
    status_cnt = 0;
    for (int i = 0; i < col_num; i++)
        col_stat *= 4;
    for (int i = 0; i < col_stat; i++)
    {
        int temp = i;
        int row_bit[4];
        row_bit[2] = row_bit[1] = row_bit[0] = 0;
        for (int j = 0; j < col_num; j++)
        {
            row_bit[0] <<= 1;
            row_bit[1] <<= 1;
            row_bit[2] <<= 1;
            row_bit[temp % 4] |= 1;
            temp /= 4;
        }
        bool conflict = false;
        for (int j = 0; j < 3; j++)
            if (!ok(row_bit[j]))
            {
                conflict = true;
                break;
            }
        if (conflict)
            continue;
        status[status_cnt].last_bit_count = count_bit(row_bit[2]);
        for (int j = 0; j < 3; j++)
            status[status_cnt].row_bit[j] = row_bit[j];
        status_cnt++;
    }
}

void work()
{
    for (int i = 0; i < row_num - 2; i++)
    {
        for (int j = 0; j < status_cnt; j++)
        {
            int a = status[j].row_bit[0];
            int b = status[j].row_bit[1];
            int c = status[j].row_bit[2];
            bool conflict = false;
            for (int k = 0; k < 3; k++)
                if (!ok(status[j].row_bit[k], i + k))
                {
                    conflict = true;
                    break;
                }
            if (conflict)
                continue;
            f[(i + 1) % 3][b][c] = max(f[(i + 1) % 3][b][c], f[i % 3][a][b] + status[j].last_bit_count);
            ans = max(ans, f[(i + 1) % 3][b][c]);
        }
    }
}

int main()
{
    input();
    if (row_num == 1)
    {
        ans = 0;
        for (int i = 0; i < (1 << col_num); i++)
        {
            if (ok(i) && ok(i, 0))
                ans = max(ans, count_bit(i));
        }
        printf("%d
", ans);
        return 0;
    }
    ans = 0;
    init();
    make_stat();
    work();
    printf("%d
", ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/rainydays/p/3466516.html