POJ - 1185 炮兵阵地

 

题意:如题

思路:由于相同行列的相邻两个格子都不能放所以用二进制模拟

由于相邻两个的状态比较少

所以有效的状可以打表出来优化时间

ACcode:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char maze[110][20];
long long vis[110];
long long dp[110][70][70];
long long num[70];
long long Count[70];
long long n,m,cnt;
long long ans;
long long Flag(long long  x){
    if( (x&(x<<1)) !=0  || (x&(x<<2)) != 0 ) return 0;
    return 1;
}
long long Cnt(long long x){
   long long res = 0;
   for(long long  i=0;i<12;i++) if( (x &(1<<i)) !=0 ) res++;
   return res;
}
int main(){
    while(scanf("%lld%lld",&n,&m)!=EOF){
        if(n == 0 && m == 0)  break;
        long long mark = (1<<m)-1;
        cnt = 0;
        for(long long i=0;i<=mark;i++){
            if(Flag(i) == 1){
                num[++cnt]=i;
                Count[cnt]=Cnt(i);
            }
        }
        memset(dp,0,sizeof dp);
        memset(vis,0,sizeof vis);
        for(long long  i=1;i<=n;i++){
            scanf("%s",maze[i]);
            for(long long j=0;j<m;j++){
                if(maze[i][j] == 'H')  vis[i]|=(1<<j);  
            }
        }
        ans = 0;
        for(long long i=1;i<=n;i++){
            for(long long  j=1;j<=cnt;j++){
                if( (vis[i]&num[j]) == 0){
                    for(long long k=1;k<=cnt;k++){
                        if((num[j]&num[k]) == 0 ){
                            for(long long x=1;x<=cnt;x++){
                                if( (num[j]&num[x]) == 0 && (num[k]&num[x]) == 0 ){  //当上个状态 及上个状态的上个状态均符合题意
                                        dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][x]+Count[j]);
                                        ans = max(ans,dp[i][j][k]);
                                }
                            }

                        }
                    }
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值