您的位置:首页 > 其它

POJ 1185(状态压缩dp)

2016-08-11 22:37 330 查看
#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);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  压缩 poj dp