POJ-1185- artillery (like pressure DP)

Artillery

Command N generals intend to deploy their artillery on a grid map of M. N a M from the map M columns of N rows, each cell may be mountain map (indicated by "H"), it may be plain (indicated by "P"), as shown below. It can be arranged on each cell up to a plain terrain artillery (not to deploy artillery on the mountain); a range artillery attack on a map as shown in the black area below:
Here Insert Picture Description

If the deployment of an artillery plain gray map identified, the figure represents a black grid to a region that can attack: two each along the left and right lateral frame, two cells up and down in the longitudinal direction. The figure was not attack other white grid. Visible effects of artillery attacks against a range of terrain from the map.
Now, the generals were planning how to deploy artillery, under the premise of preventing accidental injury (guarantee not attack each other between any two artillery units, that is, any one artillery unit is not within the scope of the attack other artillery support) throughout the map the maximum number of the army's artillery units can be placed in the area.

Input

The first line contains two positive integers separated by spaces apart, N and M, respectively;
the next N rows, each row comprising M consecutive characters ( 'P' or 'H'), with no spaces. Order data representing a map of each line. N <= 100; M <= 10.

Output

Only one line contains an integer K, represents the number up to the placing of artillery.

Sample Input


5 4
PHPP
PPHH
PPPP
PHPP
PHHP

Sample Output


6

Problem-solving ideas:

Meaning of the questions: have a map H, P in two spot, P can put artillery, artillery can attack each two adjacent vertical and horizontal grid places. Asked the maximum number of artillery can not attack each other put.
Almost naked DP Yeah, to note is that artillery can attack two layers. So when down by layers of DP needs to know what is on the floor and on the upper layer of the state, it is necessary to add a dimension. Save State on the floor. dp [i] [j] [ k] denotes the i-th layer, the mark [j] state, the upper layer is able to put the maximum of the artillery mark [k] state.
Since overtime pay several times. I do not know where to, where it changed a bunch of time can be optimized.

AC Code:

//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <algorithm>
#include <map>
#include <queue>
#include <deque>
#define ios std::ios::sync_with_stdio(false)
#define int long long
using namespace std;
const int N = 100;
int cnt = 0;	// 记录状态数
int mark[61];	// 状态最多60种,开大了还超内存
int dp[102][61][61];	
int a[102];	   // 整数记录每行的地图,优化时间
int value[61]; // 保存每个状态下炮兵的个数,每个状态只计算一次,优化时间
int n,m,en;	   // en用来确定右边界,只计算一次(1<<m) 优化时间

bool check(int lev,int sta)
{
    if((sta&a[lev]) != 0)
        return false;
    return true;
}

int count_(int x)
{
    int res = 0;
    while(x)
    {
        res ++;
        x -= (x&(-x)); // lowbit优化时间
    }
    return res;
}

signed  main()
{
    for(int i = 0 ; i < (1<<10) ; i ++)
        if(((i>>1)&i) == 0 && ((i>>2)&i) == 0)
        {
            value[cnt]  = count_(i);
            mark[cnt++] = i;
        }
    mark[cnt] = (1<<12); // 设定一个最大的右边界,不然会出现死循环
    cin>>n>>m;    en = (1<<m);
    for(int i = 0 ; i < n ; i ++)
    {
        int tmp = 0;
        for(int j = 0 ; j < m ; j ++)
        {
            char buf;  cin>>buf;
            if(buf == 'H')  tmp += (1<<(m-1-j));
        }
        a[i] = tmp;
    }
    memset(dp,0,sizeof(dp));
    for(int i = 0 ; mark[i] < en ; i ++) // 先处理第一层的情况
    {
        bool flag = check(0,mark[i]);
        int  val = value[i];
        for(int j = 0 ; mark[j] < en ; j ++)
        {
            if(flag && (mark[i]&mark[j]) == 0)
                dp[0][i][j] = val;
            else
                dp[0][i][j] = 0;
        }
    }
    for(int i = 1; i < n ; i ++)  // 枚举层数
    {
        for(int j = 0 ; mark[j] < en ; j ++) // 枚举当前层状态
        {
           if(!check(i,mark[j])) continue;
           int val = value[j];
           for(int k = 0 ; mark[k] < en ; k ++) // 枚举上一层状态
           {
               if((mark[j]&mark[k]) != 0) continue;
               for(int l = 0 ; mark[l] < en ; l ++) // 枚举上上层状态
               {
                    if((mark[j]&mark[l]) != 0 || (mark[k]&mark[l]) != 0) continue;
                    dp[i][j][k] = max(dp[i][j][k],dp[i-1][k][l]+val);
               }
           }
        }
    }
    int ans = 0;
    for(int j = 0 ; mark[j] < en ; j ++) 
        for(int k = 0 ; mark[k] < en ; k ++)
            ans = max(dp[n-1][j][k],ans);
    cout<<ans<<endl;
    return 0;
}
/** 
代码超时的话可以试试这组数据
100 10
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
PHPPPHPPPP
PPHHPPHHHH
PPPPPPPPPP
PHPPPHPPPP
PHHPPHHPHP
**/

Published 104 original articles · won praise 7 · views 4064

Guess you like

Origin blog.csdn.net/qq_43461168/article/details/104189562