比赛 状态压缩DP练习 评测结果 AAAAAAAAAA
题目名称 炮兵阵地 最终得分 100
用户昵称 梦那边的美好ET 运行时间 0.670 s
代码语言 C++ 内存使用 17.96 MiB
提交时间 2019-05-28 19:38:13
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
int mp[102],num[(1<<10)-1];
int z[1200];
bool q[102][15];
int f[102][105][105];
int n,m,ans,tot;
inline bool ok(int x,int y){
	if(z[x]&mp[y])
	   return 0;
	return 1;
}
int sd(int y){
	int sum=0;
	while(y){
		if(y>0){
			if(y&1)
			  sum++;
			y>>=1;
		}
	}
	return sum;
}
int main(){
	freopen("cannon.in","r",stdin);
	freopen("cannon.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		char x;
		for(int j=1;j<=m;++j){
			cin>>x;
			if(x=='H')
			 {
			    mp[i]+=(1<<(j-1));
			 }
		}
	}
	 for(int x=0;x<(1<<m);++x){
	 	if((x&(x<<1))||(x&(x<<2)))
	 	  continue;
	 	else
	 	  {
	 	  	z[++tot]=x;
	 	  	num[x]=sd(x);
	 	  }
	 }
	 for(int i=1;i<=tot;++i)
	   if(ok(i,1))
	      {
	      	f[1][i][0]=num[z[i]];
	      }
	 for(int j=1;j<=tot;++j){
	 	if(ok(j,2)){
	 		for(int k=1;k<=tot;++k){
	 			if(ok(k,1)){
	 				if(!(z[j]&z[k])){
	 					{
						   f[2][j][k]=max(f[2][j][k],f[1][k][0]+num[z[j]]);
	 					}
	 				}
	 			}
	 		}
	 	}
	 }
	 for(int i=3;i<=n;++i)
	   for(int j=1;j<=tot;++j){
	   	 if(ok(j,i)){
	   	 	for(int k=1;k<=tot;++k){
	   	 		if(ok(k,i-1)){
	   	 			for(int h=1;h<=tot;++h){
	   	 				if(ok(h,i-2)){
	   	 					if((!(z[h]&z[k])&&(!(z[k]&z[j]))&&(!(z[h]&z[j])))){
	   	 						f[i][j][k]=max(f[i][j][k],f[i-1][k][h]+num[z[j]]);
	   	 					}
	   	 				}
	   	 			}
	   	 		}
	   	 	}
	   	 }
	   }
	   if(n==1){
	   	for(int i=1;i<=n;++i)
	   	 ans=max(ans,f[1][i][0]);
	   }
	   for(int k=1;k<=tot;++k)
	   for(int i=1;i<=tot;++i){
	   	  ans=max(ans,f[n][k][i]);
	   }
	   printf("%d",ans);
	return 0;
}