POJ 1185(状态压缩dp)

来源:互联网 发布:自己怎样做软件 编辑:程序博客网 时间:2024/05/16 12:03
#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include<algorithm>using namespace std;int dp[105][65][65];    int s[105]; int n, m;      int S;   int map[105];  int sum[105];bool TwoNear(int x){    if (x&(x << 1))    {        return false;    }    else if (x&(x << 2))    {        return false;    }    else    {        return true;    }}int GetBits(int x){    int num = 0;    while (x)    {        if (x & 1)        {            num++;        }        x >>= 1;    }    return num;}void find(){    memset(s, 0, sizeof(s));    for (int i = 0; i<(1 << m); i++)      {        if (TwoNear(i))        {            s[S] = i;            sum[S++] = GetBits(i);        }    }}int main(){    while (~scanf("%d%d", &n, &m))    {        memset(dp, 0, sizeof(dp));        int r,i,j,p,q;        for (i = 0; i<n; i++)        {            for (int j = 0; j<m; j++)            {                char temp;                cin >> temp;                if (temp == 'H')                {                    map[i] = map[i] | (1 << j);                }            }        }        S= 0;        find();        for (i = 0; i < S; i++)        {            if (!(s[i] & map[0]))            {                dp[0][i][0] = sum[i];            }        }        for (r = 1; r<n; r++)        {            for (i = 0; i<S; i++)            {                if (map[r] & s[i])                {                    continue;                }                for (p = 0; p<S; p++)                {                    if (s[i] & s[p])                    {                        continue;                    }                    for ( q = 0; q<S; q++)                    {                        if (s[i] & s[q])                        {                            continue;                        }                        if (dp[r - 1][p][q] == 0)                        {                            continue;                        }                        dp[r][i][p] = max(dp[r][i][p], dp[r - 1][p][q] + sum[i]);                    }                }            }        }        int Max = 0;        for (i = 0; i<S; i++)            for (j = 0; j<S; j++)                Max = max(Max, dp[n - 1][i][j]);        printf("%d\n", Max);    }    system("pause");    return 0;}

二维错误原样分析

#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include<algorithm>using namespace std;int map[105];int N, M;int state[1 << 11];int S = 0;int dp[105][1 << 11];int GetBits(int x){    int Count = 0;    while (x)    {        x = x & (x - 1);        Count++;    }    return Count;}bool TwoNear(int x){    if (x&x << 1)        return false;    else if (x&x << 2)        return false;    else        return true;}void SolveRow(){    int i;    for (i = 0; i < 1 << M; i++)        if (TwoNear(i))            state[S++] = i;}int main(){    while (~scanf("%d%d", &N, &M))    {        memset(dp, 0, sizeof(dp));        memset(state, 0, sizeof(state));        memset(map, 0, sizeof(map));        int i, j, k, x;        for (i = 0; i < N; i++)        {            for (j = 0; j < M; j++)            {                char ch;                cin >> ch;                if (ch == 'H')                {                    map[i] = map[i] | 1 << j;                }            }        }        SolveRow();        for (i = 0; i <S; i++)        {            if (!(map[0] & state[i]))            {                dp[0][i] = max(dp[0][i], GetBits(state[i]));            }        }        for (i = 0; i < S; i++)        {            for (k = 0; k < S; k++)                if (!(map[1] & state[i]) && !(state[i] & state[k]))                {                dp[1][i] = max(dp[1][i], GetBits(state[i]) + GetBits(state[k]));                }        }        for (i = 2; i < N; i++)        {            for (j = 0; j < S; j++)            {                if (map[i] & state[j])                    continue;                for (k = 0; k < S; k++)                {                    if (map[i - 1] & state[k] || state[k] & state[j])                        continue;                    for (x = 0; x < S; x++)                    {                        if (map[i - 2] & state[x] || state[x] & state[j] || state[x] & state[k])                            continue;                        else                            dp[i][j] = max(dp[i][j], dp[i - 1][k] + GetBits(state[j]));                        //dp[i-1][k]储存的是第i-1行时的最大可放个数,但当到第i行时,第i-2行                        //的状态无法记录,如样例数据,当state[x]=0,state[k]=2 state[j]=1时,dp[i-1][k]=3(之前一轮循环算的),结果dp[i][j]=4;                    }                }            }        }        int Max = 0;        for (i = 0; i < S; i++)            if (!(state[i] & map[N - 1]))                Max = max(Max, dp[N - 1][i]);        printf("%d\n", Max);    }}
0 0
原创粉丝点击