power oj 2480 放积木[二进制状压DP]

题目链接【https://www.oj.swust.edu.cn/problem/show/2480】

题意:中文题目。

题解:二进制状态转移+坏点判断。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1 << 12;
LL dp[2][maxn];
int mp[15];
char s[15];
int n, m;
int cur;
void DFS(int r, int pos, int nu, int z, int cnt)
{
    if(pos == m)
    {
        dp[cur][nu] = max(dp[cur][nu], dp[cur ^ 1][z] + cnt);
        return ;
    }
    if(mp[r] & (1 << pos)) //坏点
    {
        DFS(r, pos + 1, nu, z, cnt);
        return ;
    }
    if(!(z & (1 << pos)) && !(mp[r - 1] & (1 << pos)))
        DFS(r, pos + 1, nu | (1 << pos), z, cnt + 1);
    else
    {
        if( pos && !(nu & (1 << (pos - 1))) && !(mp[r] & (1 << (pos - 1))) )
            DFS(r, pos + 1, nu | (1 << pos) | (1 << (pos - 1)), z, cnt + 1);
        DFS(r, pos + 1, nu, z, cnt);
    }
}
int main ()
{
    while(~scanf("%d%d", &n, &m))
    {
        memset(mp, 0, sizeof(mp));
        for(int i = 1; i <= n; i++)
        {
            scanf("%s", s);
            for(int j = 0; j < m; j++)
                if(s[j] == '*') mp[i] |= 1 << j;
        }
        cur = 0;
        memset(dp[0], -1, sizeof(dp[0]));
        int mask = (1 << m) - 1;
        dp[0][mask] = 0;
        for(int i = 1; i <= n; i++)
        {
            cur ^= 1;
            memset(dp[cur], -1, sizeof(dp[cur]));
            for(int j = 0; j <= mask; j++)
                if(dp[cur ^ 1][j] >= 0)
                    DFS(i, 0, 0, j, 0);
        }
        LL ans = 0;
        for(int i = 0; i <= mask; i++)
            ans = max(ans, dp[cur][i]);
        printf("%lld
", ans);
    }
    return 0;
}
想的太多,做的太少。
原文地址:https://www.cnblogs.com/pealicx/p/6234712.html