poj 1185 炮兵阵地

<textarea cols="90" rows="177" name="code" class="cpp">//poj 1185 炮兵阵地 /* 又一道状态压缩DP ,最烦的题,没心思精简代码,1700多MS低空飞过。。。 */ #include&lt;iostream&gt; using namespace std; int n,m; char str[12]; int grid[102]; int dp[101][70][70]; //dp[n][i][j]表示d到第n行,第n行和第n-1行分别为状态i,j的最大炮兵数。 int state[70],c; //dfs一遍把所有状态记录下来,由于限制大,所以其实状态不多,这是本题不TLE也不MLE的关键 void dfs(int step,int s) { if (step&gt;=m) { state[c++]=s; return ; } dfs(step+1,s); if (step&gt;1 &amp;&amp; (s &amp; (1&lt;&lt;(step-1)) )==0 &amp;&amp; ( s &amp; (1&lt;&lt;(step-2)) )==0 || step==1 &amp;&amp; (s &amp; (1&lt;&lt;(step-1)) )==0 || step==0) dfs(step+3,s|(1&lt;&lt;step)); } int ones(int a) { int ans=0; for (;a;a&gt;&gt;=1) ans+=a&amp;1; return ans; } bool collipse(int g1,int s1,int g2,int s2) { for (int i=0;i&lt;m;i++) if ( (s2&amp;(1&lt;&lt;i)) &amp;&amp; (g2&amp;(1&lt;&lt;i))==0 &amp;&amp; (s1&amp;(1&lt;&lt;i)) &amp;&amp; (g1&amp;(1&lt;&lt;i))==0 ) return true; return false; } int main() { while (scanf("%d%d",&amp;n,&amp;m)!=EOF) { c=0; dfs(0,0); memset(grid,0,sizeof(grid)); for (int i=1;i&lt;=n;i++) { scanf("%s",str); for (int j=0;j&lt;m;j++) if (str[j]=='H') grid[i]|=1&lt;&lt;j; } memset(dp,-1,sizeof(dp)); for (int i=0;i&lt;c;i++) if ((state[i]&amp;grid[1])==0) dp[1][i][0]=ones(state[i]); for (int i=2;i&lt;=n;i++) { for (int j=0;j&lt;c;j++) if ((grid[i]&amp;state[j])==0) for (int k=0;k&lt;c;k++) if ((grid[i-1]&amp;state[k])==0 &amp;&amp; !collipse(grid[i-1],state[k],grid[i],state[j])) { for (int v=0;v&lt;c;v++) if ((state[v]&amp;grid[i-2])==0 &amp;&amp; !collipse(grid[i-2],state[v],grid[i-1],state[k]) &amp;&amp; !collipse(grid[i-2],state[v],grid[i],state[j])) { if(dp[i-1][k][v]!=-1) dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][v]+ones(state[j]) ); } } } int ans=0; for (int i=0;i&lt;c;i++) if ((grid[n-1]&amp;state[i])==0) for (int j=0;j&lt;c;j++) if ((grid[n]&amp;state[j])==0 &amp;&amp; !collipse(grid[n-1],state[i],grid[n],state[j])) ans=max(ans,dp[n][j][i]); printf("%d/n",ans); } system("pause"); return 0; } </textarea>

你可能感兴趣的:(poj 1185 炮兵阵地)