状压90求助,最后一个点TLE,开O2才过

P2704 [NOI2001] 炮兵阵地

zyzbldnb @ 2023-01-31 11:51:32


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1<<10;
int f[101][maxn+5][maxn+5];// 
char a[105][14];
int get1(int x)
{
    int ans=0;
    while(x>0)
    {
        if(x&1) ans++;
        x=x>>1;
    }
    return ans;
}
bool check(int st,int l)
{
    if(st>>1&st) return 0;  // 有相邻的
    if(st>>2&st) return 0;  //有间隔1的
    for(int i=0;st>>i;i++)
      if( (st>>i&1 )&&a[l][i+1]=='H') return 0;  
    return 1;
}
int main()
{
    int n,m,ans=0;bool t=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        cin>>a[i][j];
        //if(a[i][j]=='H') t=1;
    }
    //if(!t)//无H
    //{cout<< ((n-1)/3+1)*( (m-1)/3+1);return 0;}

    for(int i=0;i<1<<m;i++)
    {
        if(!check(i,1)) continue;
      f[1][i][0]=get1(i);ans=max(ans,f[1][i][0]);
    }
    for(int i=2;i<=n;i++)
    for(int j=0;j<1<<m;j++)//第i行
    for(int k=0;k<1<<m;k++)//i-1
    {
        if(j&k || (!check(j,i))||!check(k,i-1)) continue;
        for(int l=0;l<1<<m;l++) //i-2行状态
        {
          if(!check(l,i-2)||(l&j)) continue;
          f[i][j][k]=max(f[i-1][k][l]+get1(j),f[i][j][k]);
          //ans=max(ans,f[i][j][k]);
        }
    }
    for(int i=0;i<1<<m;i++)
    for(int j=0;j<1<<m;j++)
    ans=max(ans,f[n][i][j]);
    cout<<ans;
     return 0;
}
```cpp

|