給你一張有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
#includeusingnamespace
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 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 如果在地圖中的括號所標識的平原上部署一支炮兵部隊,則圖中的黑色的網...