POJ

来源:互联网 发布:饥荒联机网络较差 编辑:程序博客网 时间:2024/06/14 06:03

图比较小,直接把所有满足的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] <<endl;        }    }    cout << Max << endl;}int main(){    scanf("%d%d",&row,&col);    Get();    Init_State();    Init1();    Init2();    DP();    print();    return 0;}

原创粉丝点击