poj1185 炮兵陣地

2021-07-22 09:54:42 字數 1314 閱讀 9314

/*

狀態壓縮+位運算

假設山地:1,空地:0,空地放兵:1,那麼每一行就是乙個01串,可以用二進位制了

首先,列舉每一行合法的放炮方法,就是不會打到彼此,與操作只有在兩個數都是1的情況下為真

假設狀態為i,(i<<1)&i相當於比較i的相鄰兩位,不打到彼此的話(i<<1)&i==0,就是沒有相鄰的兩個1

所以合法的狀態為(i<<1)&i==0 && (i<<2)&i==0

把這些合法的狀態儲存在state裡面

原地圖壓縮在ori裡面,合法狀態還有滿足炮不放在山上,那麼只要ori裡1所在的那個位置對應state裡沒有1

就可以了,即state[i]&base[i]=0

ps:選出來的state裡山地對應的位置是0

i行,i-1行,i-2行兩兩不能攻擊對方,類似的

state[i]&state[i-1]=0 state[i]&state[i-2]=0 state[i-1]&state[i-2]=0

dp[r][i][j]表示第r行狀態為state[i],r-1行為state[j]的最大值

dp[r][i][j]=max(dp[r][i][j],dp[r-1][j][k]+soldier[i])

*/#include

#include

#include

using namespace std;

#define maxr 110

#define maxc 15

#define maxn 70

#define mem(a) memset(a,0,sizeof(a))

#define check(a,b) (a)&(b) //判斷合法

int row,col;

int sum;//合法狀態數

int ori[maxn];

int state[maxn];

int soldier[maxn];//state[i]狀態下放的士兵數

int dp[maxn][maxn][maxn];

char g[maxr][maxc];

int main()

state[sum++]=i;}

//初始化第一行狀態

for(int i=0;i

//初始化第二行狀態

for(int i=0;i

//從第3行開始直到最後

for(int r=2;r

for(int k=0;k

dp[r][i][j]=max(dp[r][i][j],dp[r-1][j][k]+soldier[i]);}}

}}int ans=0;

for(int i=0;i

poj 1185 炮兵陣地

題目鏈結 題意 在n m的網格地圖上部署炮兵部隊。地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中...

POJ 1185 炮兵陣地

include include include include include include include include include include include include include include define sz v int v size define rep i,n ...

POJ 1185 炮兵陣地

狀態壓縮專題第一題,自己想了很久,最終還是以別人的 為模板寫的。dp共三維,一維是行數,一維是前一行狀態,一維是前第二行狀態。ps 直接開三維太大,用s陣列記錄下所有可能出現的情況,大大減少時間和空間。include include include includeusing namespace st...