NOI2001 炮兵陣地

2022-05-12 05:21:29 字數 1177 閱讀 9875

給你一張有n*m的平原和山地的圖,只能在平原上放置炮兵,炮兵的攻擊範圍如圖所示,求最多能放多少個炮兵?

資料規模:n <= 100;m <= 10。

此題比起入門級的狀壓,難在了狀態更多,影響的也不只一行了,而是兩行。

所以我們需要加維+減狀態

dp[i][j][k],掃到i行為止,當前行的狀態為j,上一行的狀態為k的方案最大值。

如果再把山地的算進去,狀態就太多了,需要預處理剪掉一些。

而相應的,預處理也要預處理1,2兩行,列舉第i行時也必須列舉i-1行,i-2行。

減狀態的方法:對映。用cnt表示可行狀態編號,id[ ]陣列對應了這個狀態

還需要預處理出每個狀態可以放置多少炮兵,便於統計答案

注意好好算一下陣列開多大,一念之差很容易re or mle

#includeusing

namespace

std;

#define n 110

#define ll long longll ans=0

,dp[n][n][n],num[n];

intn,m,mx,cnt;

inte[n][n],ok[n],okk[n][n],id[n];

intmp[n];

string

s;int

main()

mx=(1

<1

;

for(int i=1;i<=n;i++)

for(int j=1;j<=m;j++)

mp[i]=(mp[i]<<1)+e[i][j];

for(int i=0;i<=mx;i++)

}}

for(int i=1;i<=cnt;i++)

if(ok[i] & ((id[i]&mp[1])==id[i]))

for(int i=1;i<=cnt;i++)

}}

for(int i=3;i<=n;i++)

for(int j=1;j<=cnt;j++)}}

}for(int i=1;i<=cnt;i++)

for(int j=1;j<=cnt;j++)

ans=max(ans,dp[n][i][j]);

cout

<

return

0;

}

NOI 2001 炮兵陣地

分析 本來想的和周偉nei胖子差不多 但是感覺時間會炸,於是又苟且看了講解 發現胖子果然用會炸的方法 但是畢竟十幾年前的題了 資料略弱 dp i j k 表示前i行中,第i行狀態為j,第i 1行狀態為k時炮兵的最多數量 狀態均為01的二進位制串 方程很好寫 dp i j k max dp i j k...

NOI2001 炮兵陣地

司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的括...

NOI2001 炮兵陣地

司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 如果在地圖中的括號所標識的平原上部署一支炮兵部隊,則圖中的黑色的網...