【NOI2001】炮兵阵地
生活随笔
收集整理的這篇文章主要介紹了
【NOI2001】炮兵阵地
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
【題意】
給定一張n*m的圖,每個(gè)位置要么是P,要么是H。P的位置可以放炮兵,H則不行。炮兵會(huì)朝四個(gè)方向,距離2個(gè)單位的方格進(jìn)行攻擊,求在沒有炮兵互傷的情況下,最多能放的炮兵數(shù)量。
【題解】
這道題死坑。
一開始知道是狀壓dp。但是狀態(tài)想的比較麻煩,寫了半天沒寫出來。
看了網(wǎng)上其它神犇的題解,發(fā)現(xiàn)狀態(tài)很簡(jiǎn)單:DP[I][J][K],表示當(dāng)前為第I行,第I行狀態(tài)為J,第I-1狀態(tài)為K,狀態(tài)轉(zhuǎn)移方程比較好想的。
不過每一行無腦算狀態(tài)有最多大概1000種,狀態(tài)顯然存不下。考慮一下題目的限制,估算一下每一行的合法狀態(tài)不超過100個(gè)吧。于是先預(yù)處理出合法狀態(tài),再標(biāo)一下號(hào)就行了。
其實(shí)難點(diǎn)還是在狀態(tài)的構(gòu)造吧(可能我比較腦殘)。
時(shí)間復(fù)雜度O(n*k^3),k表示狀態(tài)數(shù)。
【代碼】
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #define N 105 5 using namespace std; 6 pair <int,int> p[N][N]; 7 int n,m,ans,dp[N][N][N],x,y,z,len[N]; 8 char a[N][N]; 9 void dfs(int i,int t,int s,int k) 10 { 11 if (t==m) 12 { 13 p[i][++len[i]]=make_pair(s,k); 14 return; 15 } 16 dfs(i,t+1,s<<1,k); 17 if (a[i][t+1]=='P' && (s&3)==0) dfs(i,t+1,(s<<1)+1,k+1); 18 } 19 int main() 20 { 21 cin>>n>>m; 22 for (int i=1;i<=n;++i) 23 { 24 cin>>a[i]+1; dfs(i,0,0,0); 25 } 26 len[0]=1; 27 for (int i=1;i<=len[1];++i) 28 dp[1][1][i]=p[1][i].second; 29 ans=0; 30 for (int i=2;i<=n;++i) 31 for (int j=1;j<=len[i-2];++j) 32 for (int k=1;k<=len[i-1];++k) 33 { 34 x=p[i-2][j].first; 35 y=p[i-1][k].first; 36 if ((x&y)) continue; 37 for (int o=1;o<=len[i];++o) 38 { 39 z=p[i][o].first; 40 if ((x&z)||(y&z)) continue; 41 dp[i][k][o]=max(dp[i][k][o],dp[i-1][j][k]+p[i][o].second); 42 if (i==n) ans=max(ans,dp[i][k][o]); 43 } 44 } 45 cout<<ans<<endl; 46 return 0; 47 } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/Bleacher/p/6857556.html
總結(jié)
以上是生活随笔為你收集整理的【NOI2001】炮兵阵地的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pandas入门(2)
- 下一篇: centOS改编码