poj 1185 炮兵陣地

來源:互聯網
上載者:User
炮兵陣地
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 15275   Accepted: 5749

Description

司令部的將軍們打算在N*M的網格地圖上部署他們的炮兵部隊。一個N*M的地圖由N行M列組成,地圖的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍中黑色地區所示: 


如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表示它能夠攻擊到的地區:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網格均攻擊不到。從圖上可見炮兵的攻擊範圍不受地形的影響。 
現在,將軍們規劃如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖地區內最多能夠擺放多少我軍的炮兵部隊。 

Input

第一行包含兩個由空格分割開的正整數,分別表示N和M; 
接下來的N行,每一行含有連續的M個字元('P'或者'H'),中間沒有空格。按順序表示地圖中每一行的資料。N <= 100;M <= 10。

Output

僅一行,包含一個整數K,表示最多能擺放的炮兵部隊的數量。

Sample Input

5 4PHPPPPHHPPPPPHPPPHHP

Sample Output

6

Source

Noi 01

思路:

狀態要設定三個因為和上面兩個狀態因為炮兵的攻擊範圍是影響下三行有關,dp[i][j][k] 表示第i行狀態為k,第i-1狀態為j時的最大炮兵個數。 狀態轉移方程:

dp[i][j][k] =max(dp[i][j][k],dp[i-1][l][j]+sum[k]); sum[k]為k狀態中1的個數 ;

#include <iostream>#include<stdio.h>#include<string.h>#define MAX(a,b) ((a)>(b)?(a):(b))using namespace std;int dp[101][65][65];//dp[i][j][k]表示上上行狀態為i上行狀態為j本行狀態為k的最多炮兵數int state[105];//記錄一行時可以放的狀態int sum[105];//記錄每一種狀態對應放得炮兵數int maze[105];//讀每行地圖int n,m,cnt;int isok(int x)//判斷每行內是否衝突{    if(x&(x>>1))//判斷相鄰位是否有炮兵        return 0;    if(x&(x>>2))//判斷隔一位是否有炮兵        return 0;    return 1;}int getone(int x)//計算每種狀態一的個數.即炮兵數{    int one=0;    while(x>0)    {        if(x&1)            one++;        x>>=1;    }    return one;}int main(){    int i,j,now,pre,ppre,ans;    char c;    while(~scanf("%d%d",&n,&m))    {        getchar();        cnt=0;        for(i=0; i<(1<<m); i++)        if(isok(i))//預先處理.先得到一行可行狀態        {            state[cnt]=i;            sum[cnt++]=getone(i);        }        ans=0;        memset(maze,0,sizeof maze);        memset(dp,0,sizeof dp);        for(i=1; i<=n; i++)        {            for(j=0; j<m; j++)//處理地圖.把地圖變成01序列            {                scanf("%c",&c);                if(c=='H')//是h就記為1.方便後面判斷是否與地圖衝突                    maze[i]=maze[i]|(1<<j);            }            getchar();        }        for(i=0;i<cnt;i++)            if(!(state[i]&maze[1]))//初始化第一行              dp[1][0][i]=sum[i];        for(i=2;i<=n;i++)        {            for(now=0;now<cnt;now++)//枚舉本行狀態            {                if(state[now]&maze[i])//判斷本行狀態與地圖是否衝突                    continue;                for(pre=0;pre<cnt;pre++)//枚舉前一行                {                    if(state[pre]&maze[i-1])                        continue;                    if(state[now]&state[pre])//本行與前一行是否衝突                        continue;                    for(ppre=0;ppre<cnt;ppre++)//枚舉上上行                    {                        if(state[ppre]&state[now])                            continue;                        if(state[ppre]&state[pre])                            continue;                        if(state[ppre]&maze[i-2])                            continue;                        dp[i][pre][now]=MAX(dp[i][pre][now],dp[i-1][ppre][pre]+sum[now]);                    }                }            }        }        for(i=0;i<cnt;i++)            for(j=0;j<cnt;j++)                if(dp[n][i][j]>ans)                  ans=dp[n][i][j];        printf("%d\n",ans);    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.