您的位置:首页 > 其它

POJ - 1185 (状压DP)

2017-10-05 16:48 246 查看
图比较小,直接把所有满足的state都找出来,所有的state和图上对应的行取 & 判断是不是符合本行就行了。

dp[k][i][j]代表第k行为状态state[i]第k-1行为状态state[j] 的状态下最多安多少个炮兵。



#include <iostream>
#include <cstdio>
using namespace std;
const int MAXR = 110;
const int MAXC = 15;
const int MAXM = 70;

int judge(int a, int b)
{
return a & b;
}

int row, col;
int nums;
int soldier[MAXR];// 状态编号为i的状态有多少个兵团
int base[MAXR];
int state[MAXM];//编号为i的状态的值
int dp[MAXR][MAXM][MAXM];
char g[MAXR][MAXC];

void Get()
{
scanf("%d%d",&row, &col);
for(int i = 0 ; i < row ; i++)
{
scanf("%s",g[i]);
for(int j = 0 ; j < col ; j++)
{
if(g[i][j] == 'H')
{
base[i] += (1 << j);
}
}
}
}
int Num_State = 0;
void Init_State()
{
Num_State = 0;
for(int i = 0 ; i < (1<<col) ; i++)
{
if(judge(i, i<<1) || judge(i,i<<2))continue; // 移动后和原来取&就可以判断是不是存在间距小于2的兵团
int x = i;
while(x)
{
soldier[Num_State] += (x%2);
x /= 2;
}
state[Num_State++] = i;
}
//    for(int i = 0 ; i < Num_State  ; i++)
//    {
//        cout << state[i] << " " << soldier[i] << endl;
//    }
//    cout << "NUM : " << Num_State << endl;
}

void Init1()
{
//dp[0][i][0];
for(int i = 0 ; i < Num_State ; i++)
{
if(base[0] & state[i]) continue;
dp[0][i][0] = soldier[i];
}
}

void Init2()
{
//dp[1][i][j]
for(int i = 0 ; i < Num_State ; i++)
{
if(base[1] & state[i]) continue;
for(int j = 0 ;  j < Num_State ; j++)
{
if(base[0] & state[j])continue;
if(state[i] & state[j])continue;
dp[1][i][j] = max(dp[1][i][j], dp[0][j][0] + soldier[i]);
}
}
}

void DP()
{
// dp[k][i][j]
for(int k = 2 ; k < row ; k++)
{
for(int i = 0 ; i < Num_State ; i++)
{
if(base[k] & state[i]) continue;
for(int j = 0 ; j < Num_State ; j++)
{
if(base[k-1] & state[j]) continue;
if(state[j] & state[i])  continue;
for(int l = 0; l < Num_State ; l++)
{
if(base[k-2] & state[l]) continue;
if(state[l] & state[i]) continue;
if(state[l] & state[j]) continue;
dp[k][i][j] = max(dp[k][i][j] , dp[k-1][j][l] + soldier[i]);
}
}
}
}
}

void print()
{
int Max = 0;
for(int i = 0 ; i < Num_State ; i++)
{
for(int j = 0 ; j < Num_State ; j++)
{
Max = max(Max , dp[row-1][i][j]);
//            cout << dp[row-1][i][j] &l
4000
t;<endl;
}
}
cout << Max << endl;
}
int main()
{
scanf("%d%d",&row,&col);
Get();
Init_State();
Init1();
Init2();
DP();
print();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: