洛谷2704 炮兵阵地

来源:互联网 发布:无头骑士异闻录 知乎 编辑:程序博客网 时间:2024/06/16 14:52

题目:炮兵阵地


思路:位运算+记忆化搜索


注意:记忆化时要存2个状态


代码:

#include <cstdio>#include <iostream>#include <algorithm>#include <stack>#include <queue>#include <deque>#include <set>#include <cstring>#include <map>using namespace std;#define maxn 100#define maxm 10int n,m;int a[maxn]={0};int b[1<<maxm]={0};int f[1<<maxm][1<<maxm][maxn]={0};int judge(int x){if(x&(x<<1)||x&(x<<2)||x&(x>>1)||x&(x>>2)) return -1;//左右不能放 int y=x,t=0,s=0;//预处理出每种状态下炮兵的个数 while(y){t=y&1;if(t==1) s++;y>>=1;}return s;}int dfs(int step,int state1,int state2){if(step==n){return 0;}int ans=0;for(int i=0;i<(1<<m);i++){if(b[i]!=-1&&!(i&state1)&&!(i&state2)&&(i|a[step])==a[step]){//不能被上方的炮误伤且只能放在平原 int x;if(f[state2][i][step]) x=f[state2][i][step];else x=f[state2][i][step]=dfs(step+1,state2,i);ans=max(ans,b[i]+x);}}return ans;}int main() {scanf("%d%d",&n,&m);for(int i=0;i<n;i++){string x;cin>>x;for(int j=0;j<m;j++){bool y;if(x[j]=='P') y=true;else y=false;a[i]=a[i]*2+y;//处理地图 }}for(int i=0;i<(1<<m);i++){b[i]=judge(i);}printf("%d",dfs(0,0,0));return 0;}


原创粉丝点击